アプリにプレビューを追加する場合は、PreviewView を使用します。これは適切な表示に合わせて切り抜き、サイズ変更、回転ができる View です。
画像プレビューは、カメラがアクティブになったときに PreviewView 内のサーフェスにストリーミングされます。
PreviewView を使用する
PreviewView を使用して CameraX のプレビューを実装するには、以下の手順(後のセクションで説明)を行います。
- 必要に応じて
CameraXConfig.Providerを設定します。 - レイアウトに
PreviewViewを追加します。 ProcessCameraProviderをリクエストします。Viewを作成するときは、ProcessCameraProviderを確認します。- カメラを選択してライフサイクルとユースケースをバインドします。
PreviewView の使用には、いくつかの制限事項があります。PreviewView を使用する場合、次のいずれの操作も実行できません。
SurfaceTextureを作成し、TextureViewとPreview.SurfaceProviderに設定する。TextureViewからSurfaceTextureを取得し、Preview.SurfaceProviderに設定する。SurfaceViewからSurfaceを取得し、Preview.SurfaceProviderに設定する。
これらのうちいずれかの操作が行われた場合、Preview は PreviewView へのフレームのストリーミングを停止します。
PreviewView をレイアウトに追加する
次のサンプルは、レイアウト内の PreviewView を示しています。
<FrameLayout android:id="@+id/container"> <androidx.camera.view.PreviewView android:id="@+id/previewView" /> </FrameLayout>
CameraProvider をリクエストする
次のコードは、CameraProvider をリクエストする方法を示しています。
Kotlin
import androidx.camera.lifecycle.ProcessCameraProvider import com.google.common.util.concurrent.ListenableFuture class MainActivity : AppCompatActivity() { private lateinit var cameraProviderFuture : ListenableFuture<ProcessCameraProvider> override fun onCreate(savedInstanceState: Bundle?) { cameraProviderFuture = ProcessCameraProvider.getInstance(this) } }
Java
import androidx.camera.lifecycle.ProcessCameraProvider import com.google.common.util.concurrent.ListenableFuture public class MainActivity extends AppCompatActivity { private ListenableFuture<ProcessCameraProvider> cameraProviderFuture; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { cameraProviderFuture = ProcessCameraProvider.getInstance(this); } }
CameraProvider が利用可能かどうかを確認する
CameraProvider をリクエストした後、ビューの作成時に初期化が成功したことを確認します。次のコードに、その方法を示します。
Kotlin
cameraProviderFuture.addListener(Runnable { val cameraProvider = cameraProviderFuture.get() bindPreview(cameraProvider) }, ContextCompat.getMainExecutor(this))
Java
cameraProviderFuture.addListener(() -> { try { ProcessCameraProvider cameraProvider = cameraProviderFuture.get(); bindPreview(cameraProvider); } catch (ExecutionException | InterruptedException e) { // No errors need to be handled for this Future. // This should never be reached. } }, ContextCompat.getMainExecutor(this));
たとえば、このサンプルで使用されている bindPreview 関数については、次のセクションに示されているコードをご覧ください。
カメラを選択してライフサイクルとユースケースをバインドする
CameraProvider を作成して確認したら、次のようにします。
Previewを作成します。- 希望のカメラの
LensFacingオプションを指定します。 - 選択したカメラとユースケースをライフサイクルにバインドします。
PreviewをPreviewViewに接続します。
次のコードに、例を示します。
Kotlin
fun bindPreview(cameraProvider : ProcessCameraProvider) { var preview : Preview = Preview.Builder() .build() var cameraSelector : CameraSelector = CameraSelector.Builder() .requireLensFacing(CameraSelector.LENS_FACING_BACK) .build() preview.setSurfaceProvider(previewView.getSurfaceProvider()) var camera = cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, preview) }
Java
void bindPreview(@NonNull ProcessCameraProvider cameraProvider) { Preview preview = new Preview.Builder() .build(); CameraSelector cameraSelector = new CameraSelector.Builder() .requireLensFacing(CameraSelector.LENS_FACING_BACK) .build(); preview.setSurfaceProvider(previewView.getSurfaceProvider()); Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, preview); }
bindToLifecycle() は Camera オブジェクトを返します。ズームや露出など、カメラ出力の制御について詳しくは、カメラ出力をご覧ください。
これでカメラ プレビューの実装は完了です。アプリをビルドし、プレビューがアプリに表示され、意図したとおりに動作することを確認します。
PreviewView の追加コントロール
CameraX PreviewView には、次のようなプロパティを設定するための追加 API が用意されています。
実装モード
PreviewView は、以下のいずれかのモードを使用して、プレビュー ストリームをターゲット View にレンダリングできます。
PERFORMANCEモード(デフォルト モード):PreviewViewはSurfaceViewを使用して動画ストリームを表示しますが、特定のケースではTextureViewにフォールバックします。SurfaceViewには専用の描画サーフェスがあり、特にプレビュー動画上に他の UI 要素(ボタンなど)がない場合、内部ハードウェア コンポジターによりハードウェア オーバーレイで実装される可能性が高くなります。ハードウェア オーバーレイでレンダリングすると、動画フレームが GPU パスを回避するので、プラットフォームの電力消費とレイテンシを削減できます。COMPATIBLEモード:PreviewViewはTextureViewを使用しますが、SurfaceViewとは異なり、専用の描画サーフェスはありません。その結果、動画を表示するにはブレンディングでレンダリングされます。このステップでは、動画を制限なしで拡大縮小したり回転させたりするなど、アプリケーションで追加の処理を実行できます。
PreviewView.setImplementationMode() を使用して、アプリケーションに適した実装モードを選択します。デフォルトの PERFORMANCE モードがアプリケーションに適していない場合のために、次のコードサンプルで COMPATIBLE モードの設定方法を示します。
Kotlin
// viewFinder is a PreviewView instance viewFinder.implementationMode = PreviewView.ImplementationMode.COMPATIBLE
スケールタイプ
プレビュー動画の解像度がターゲット PreviewView のサイズと異なる場合は、動画コンテンツを切り抜くかレターボックス表示にするかして、ビューに合わせる必要があります(アスペクト比は変えないでください)。PreviewView には、この目的のために次の ScaleTypes が用意されています。
FIT_CENTER、FIT_START、FIT_END(レターボックス表示用): 動画コンテンツ全体が、ターゲットPreviewViewで表示できる最大サイズに拡大縮小されます。ただし、動画フレーム全体が表示されても、画面の一部が空白になることがあります。選択した 3 つのスケールタイプに応じて、ターゲット ビューの中央、始点、または終点に合わせて動画フレームが配置されます。FILL_CENTER、FILL_START、FILL_END(切り抜き用): 動画がPreviewViewのアスペクト比と一致しない場合、コンテンツは一部しか表示されませんが、動画はPreviewView全体に表示されます。
CameraX が使用するデフォルトのスケールタイプは FILL_CENTER です。PreviewView.setScaleType() を使用して、アプリケーションに最適なスケールタイプを設定してください。次のコードサンプルでは、FIT_CENTER スケールタイプを設定しています。
Kotlin
// viewFinder is a PreviewView instance viewFinder.scaleType = PreviewView.ScaleType.FIT_CENTER
動画の表示は、以下のステップから処理されます。
- 動画を拡大縮小します。
FIT_*スケールタイプの場合、min(dst.width/src.width, dst.height/src.height)で動画を拡大縮小します。FILL_*スケールタイプの場合、max(dst.width/src.width, dst.height/src.height)で動画を拡大縮小します。
- 拡大縮小された動画を表示先
PreviewViewに合わせます。FIT_CENTER/FILL_CENTERの場合、拡大縮小された動画と表示先PreviewViewを、それぞれの中央を合わせて配置します。FIT_START/FILL_STARTの場合、拡大縮小された動画と表示先PreviewViewを、それぞれの左上端を合わせて配置します。FIT_END/FILL_ENDの場合、拡大縮小された動画と表示先PreviewViewを、それぞれの右下端を合わせて配置します。
たとえば、元になる動画が 640x480 で、表示先の PreviewView が 1920x1080 だとします。

次の図は、FIT_START / FIT_CENTER / FIT_END の拡大縮小処理を示しています。

この処理は次のように行われます。
- 動画フレームを(アスペクト比を変えずに)
min(1920/640, 1080/480) = 2.25倍に拡大して、1440x1080 の中間動画フレームを生成します。 - 1440x1080 の動画フレームを 1920x1080 の
PreviewViewに合わせます。FIT_CENTERの場合、動画フレームをPreviewViewウィンドウの中央に合わせます。PreviewViewの始点側と終点側の 240 ピクセルの列は空白です。FIT_STARTの場合、動画フレームをPreviewViewウィンドウの始点(左上端)に合わせます。PreviewViewの終点側の 480 ピクセルの列は空白です。FIT_ENDの場合、動画フレームをPreviewViewウィンドウの終点(右下端)に合わせます。PreviewViewの始点側の 480 ピクセルの列は空白です。
次の図は、FILL_START / FILL_CENTER / FILL_END の拡大縮小処理を示しています。

この処理は次のように行われます。
- 動画フレームを
max(1920/640, 1080/480) = 3倍に拡大して、1920x1440 の中間動画フレーム(PreviewViewより大きい)を生成します。 - 1920x1440 の動画フレームを 1920x1080 の
PreviewViewウィンドウに合うよう切り抜きます。FILL_CENTERの場合、拡大済みの 1920x1440 の動画の中央から 1920x1080 を切り抜きます。動画の上下 180 行は表示されません。FILL_STARTの場合、拡大済みの 1920x1440 の動画の始点から 1920x1080 を切り抜きます。動画の下側の 360 行は表示されません。FILL_ENDの場合、拡大済みの 1920x1440 の動画の終点から 1920x1080 を切り抜きます。動画の上側 360 行は表示されません。
参考情報
CameraX について詳しくは、以下の参考情報をご確認ください。
Codelab
コードサンプル