Camera2 TextureViewの回転|Android開発

      2018/06/15

Camera2 APIのプレビューで使用しているTextureViewはカメラのプレビューがportraitになるように描画されます。(スマホの場合)
そのため、landscapeでActivityを起動するとプレビューの向きがおかしくなります。
この問題に対応するため、Matrixを使ってTextureViewを回転させる必要があります。

サンプル

void configureTransform(TextureView textureView, int previewWidth, int previewHeight) {
    int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
    Matrix matrix = new Matrix();
    RectF viewRect = new RectF(0, 0, textureView.getWidth(), textureView.getHeight());
    RectF bufferRect = new RectF(0, 0, previewHeight, previewWidth);
    PointF center = new PointF(viewRect.centerX(), viewRect.centerY());
    if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
        bufferRect.offset(center.x - bufferRect.centerX(), center.y - bufferRect.centerY());
        matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
        float scale = Math.max(
                (float) textureView.getHeight() / previewHeight,
                (float) textureView.getWidth() / previewHeight);
        matrix.postScale(scale, scale, center.x, center.y);
        matrix.postRotate(90 * (rotation - 2), center.x, center.y);
    } else if (Surface.ROTATION_180 == rotation) {
        matrix.postRotate(180, center.x, center.y);
    }
    textureView.setTransform(matrix);
}

回転はmatrix.postRotate()で行っています。

本処理はカメラオープン時やonSurfaceTextureSizeChanged()でコールします。
※本サンプルはプレビューを画面いっぱいに表示しようとする手法のため、プレビューサイズとディスプレイサイズによっては実際にプレビュー出来る領域より狭い範囲が画面に描画されている可能性があります。

追記
プレビュー領域を全て描画させる場合のサンプルを用意しました。
Camera2 TextureViewの回転(プレビューアスペクト比キープ)

 - Android