カメラプレビューを実装するロジックを提供するCameraSurfaceView
クラスを作成しました。私が試したデバイスですべてうまく動作します。 Nexus 5、Nexus 5X、Nexus 6P、さらにはSamsung Galaxy S5などがあります。すべてのデバイスをサポートするためのカメラ用のアンドロイドサーフェイスビューの拡張
しかし、サムスンギャラクシーS6エッジ上の何らかの理由で、私はそれを絞られている
android.hardware.Camera.native_setParameters(ネイティブメソッド)
のランタイム例外を取得クラス内の次のもの
parameters.setPictureSize(mPreviewSize.width、mPreviewSize.height);ここで
私のクラスである:
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private Camera mCamera;
private SurfaceHolder mSurfaceHolder;
private List<Camera.Size> mSupportedPreviewSizes;
private Camera.Size mPreviewSize;
public CameraSurfaceView(Context context, Camera camera) {
super(context);
mCamera = camera;
mSurfaceHolder = getHolder();
mSurfaceHolder.addCallback(this);
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mSurfaceHolder.getSurface() == null) {
// preview surface does not exist
return;
}
try {
// stop preview before making changes
mCamera.stopPreview();
} catch (Exception e) {
Timber.e(e, e.getMessage());
}
// set preview size and make any resize, rotate or reformatting changes here
// start preview with new settings
try {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
parameters.setPictureSize(mPreviewSize.width, mPreviewSize.height);
if (parameters.getSupportedFocusModes()
.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
mCamera.setParameters(parameters);
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
} catch (Exception e) {
Timber.e(e, "Error starting camera preview: " + e.getMessage());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
float ratio;
if (mPreviewSize.height >= mPreviewSize.width) {
ratio = (float) mPreviewSize.height/(float) mPreviewSize.width;
} else {
ratio = (float) mPreviewSize.width/(float) mPreviewSize.height;
}
// One of these methods should be used, second method squishes preview slightly
setMeasuredDimension(width, (int) (width * ratio));
// setMeasuredDimension((int) (width * ratio), height);
}
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
final double aspectTolerance = 0.1;
double targetRatio = (double) h/w;
if (sizes == null) {
return null;
}
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
for (Camera.Size size : sizes) {
double ratio = (double) size.height/size.width;
if (Math.abs(ratio - targetRatio) > aspectTolerance) {
continue;
}
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
}
私はこのデバイスまたは同じ問題を持つ他の人のために正しく画像サイズを設定するにはどうすればよいですか?
誰も、ほとんどのデバイスで動作するCamera SurfaceViewロジックの良い例はありますか?
ありがとうございました。
私は同じ問題に直面し、画面の幅と高さを使って解きます。サイズのプレビューを信頼しないでください。これは、古いデバイスのほとんどが故障している可能性があります。 – asozcan