Camera2 撮影サイズから最適なプレビューサイズを決定する|Android開発

      2018/05/21

Camera2 APIで撮影サイズ決定後に撮影サイズとアスペクト比が一致するプレビューサイズを決定するサンプルです。

public void choosePreviewSize(String cameraId) {
    // 端末の向き.
    int displayRotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
    // カメラの向き.
    CameraManager cameraManager =
        (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
    int sensorOrientation;
    try {
        CameraCharacteristics characteristics =
            cameraManager.getCameraCharacteristics(cameraId);
        Integer tempSO = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
        sensorOrientation = tempSO == null ? 0 : tempSO;
    } catch (CameraAccessException e) {
        e.printStackTrace();
        sensorOrientation = 0;
    }

    int viewWidth = mTextureView.getWidth();
    int viewHeight = mTextureView.getHeight();
    switch (displayRotation) {
        case Surface.ROTATION_0:
        case Surface.ROTATION_180:
            if (sensorOrientation == 90 || sensorOrientation == 270) {
                viewWidth = mTextureView.getHeight();
                viewHeight = mTextureView.getWidth();
            }
            break;
        case Surface.ROTATION_90:
        case Surface.ROTATION_270:
            if (sensorOrientation == 0 || sensorOrientation == 180) {
                viewWidth = mTextureView.getHeight();
                viewHeight = mTextureView.getWidth();
            }
            break;
    }

    List<Size> sameAspectSizes = new ArrayList<>();
    List<Size> previewSizes = getSupportedPreviewSizes();
    for (Size previewSize : previewSizes) {
        int w = previewSize.getWidth();
        int h = previewSize.getHeight();
        if (h == w * mPictureSize.y / mPictureSize.x) {
            if (w >= viewWidth && h >= viewHeight) {
                sameAspectSizes.add(previewSize);
            }
        }
    }

    if (0 < sameAspectSizes.size()) {
        Size previewSize = Collections.min(sameAspectSizes, new Comparator<Size>() {
            @Override
            public int compare(Size lhs, Size rhs) {
                return Long.signum(((long) lhs.getWidth() * lhs.getHeight()) - ((long) rhs.getWidth() * rhs.getHeight()));
            }
        });
        mPreviewSize.set(previewSize.getWidth(), previewSize.getHeight());
    } else {
        Size previewSize = previewSizes.get(0);
        mPreviewSize.set(previewSize.getWidth(), previewSize.getHeight());
    }
}
  • mTextureViewはプレビュー表示用のTextureViewインスタンスです
  • mPictureSizeは設定済みの撮影サイズです
  • カメラの向きActivityの向きに関係なく、常に同じ値です
  • getSupportedPreviewSizes()については、Camera2 キャプチャサイズの取得を参照下さい

本サンプルではプレビュー用のTextureViewサイズより大きい最適サイズ一覧を取得sameAspectSizesし、その中で一番小さい値をプレビューサイズとして採用しています。

if (w >= viewWidth && h >= viewHeight)
Size previewSize = Collections.min(...

上記の部分を変更することで、TextureViewサイズより小さいものを選択など、取得対象を変更可能です。

 - Android