アプリにプレビューを追加する場合は、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
コードサンプル
