• トップ
  • ブログ一覧
  • CameraXでプレビューから写真撮影までしてみた
  • CameraXでプレビューから写真撮影までしてみた

    たかやん(エンジニア)たかやん(エンジニア)
    2021.01.19

    エンジニアになろう!

    CameraX で写真を撮ってみよう!

    鈴木先生

    (株)ライトコードの鈴木です!

    CameraX」は、カメラ機能を簡単に実装できる API です。

    カメラ機能を実装するなら Camera2API の方が主流でしたが、遅延処理とコールバックが必須なため、実装に手間がかかるのが難でした…。

    でも、CameraX なら「ロジックの実装」だけで良いんです!

    今回は、CameraX を使ったプレビューと撮影の実装方法をご紹介します!

    CameraX を利用するための準備

    まずは、依存関係の設定と権限の付与を行いましょう!

    ライブラリを追加

    build.gradle に、CameraX のライブラリを追加します。

    1compileOptions {
    2    sourceCompatibility JavaVersion.VERSION_1_8
    3    targetCompatibility JavaVersion.VERSION_1_8
    4}
    5
    6def camerax_version = "1.0.0-alpha07"
    7implementation "androidx.camera:camera-core:$camerax_version"
    8implementation "androidx.camera:camera-camera2:$camerax_version"

    パーミッションを追加

    次に、AndroidManifest.xml に、パーミッションの追加をしてください。

    1<uses-permission android:name="android.permission.CAMERA" />
    2<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    他の権限と同じく、カメラ機能を使用する前には権限が付与されているかの確認が必要なので、権限を求める実装を行ってください。

    CameraX を実装

    UseCase クラスで用途を決める

    一口にカメラ機能といっても、「写真や動画の撮影」「プレビュー表示」「画像解析」など利用方法は様々です。

    CameraX では、各機能を UseCase クラスで管理しており、以下の子クラスがあります。

    1. Preview クラス(プレビュー)
    2. ImageCapture クラス(画像撮影)
    3. ImageAnalysis クラス(画像解析)
    4. VideoCapture クラス(動画撮影)

    実装の流れ

    どのクラスも、実装の流れは以下のような感じです。

    1. 実装したい機能のクラスを決める
    2. リスナーの設定
    3. ライフサイクルに紐付け

    さて、それではさっそく実装していきましょう!

    プレビュー機能を実装

    プレビュー機能を実装するには「Preview クラス」を使います。

    オプション設定

    まずは、PreviewView をレイアウトに配置します。

    コードでの取得と、プレビューする時のオプションを設定していきます。

    1val previewView: Preview = findViewById(R.id.preview_view)

    PreviewView はカスタムビューで、元は SurfaceView です。

    ライフサイクルの紐付け

    次に、ProcessCameraProvider クラスのインスタンスを作成し、カメラのライフサイクルと紐づけをします。

    これで「ホーム」や「戻る」ボタンで別画面に行っても、いつでも再開できるようになります。

    1val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
    2cameraProviderFuture.addListener({
    3    val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
    4    val preview = Preview.Builder()
    5        .build().also {
    6            it.setSurfaceProvider(previewView.createSurfaceProvider())
    7        }
    8    try {
    9        cameraProvider.unbindAll()
    10        cameraProvider.bindToLifecycle(this, CameraSelector.DEFAULT_BACK_CAMERA, preview)
    11    } catch (exc: Exception) {
    12        Log.e(TAG, "プレビューの失敗", exc)
    13    }
    14}, ContextCompat.getMainExecutor(this))

    以上で、プレビュー表示は完了です!

    撮影機能を実装

    写真を撮影したい時は「ImageCapture クラス」を使います。

    「自動ホワイトバランス」「自動露出」「オートフォーカス」なども、このクラスで実装できますよ。

    オプションを設定

    最初に、撮影する際のオプションを設定しましょう。

    下記の様に設定すると、「自動でフラッシュ撮影」かつ「画質よりも低遅延を優先する」ようになります。

    1val imageCapture = ImageCapture.Builder()
    2.setFlashMode(ImageCapture.FLASH_MODE_AUTO)
    3.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
    4.build()

    撮影の処理

    次に、撮影の処理をします。

    今回は、「ボタンを押したら撮影し、test.jpg というファイル名で出力される」ようにしました。

    画像の保存に成功した時には Toast を出力し、保存に失敗したらログを出力します。

    1captureButton.setOnClickListener {
    2    imageCapture.takePicture(
    3        outputOptions,
    4        ContextCompat.getMainExecutor(this),
    5        object : ImageCapture.OnImageSavedCallback {
    6            override fun onImageSaved(output: ImageCapture.OutputFileResults) {
    7                Toast.makeText(
    8                    this@MainActivity, "Saved image to $photoFile", Toast.LENGTH_SHORT
    9                ).show()
    10            }
    11
    12            override fun onError(exc: ImageCaptureException) {
    13                Log.e(TAG, "${exc.message}", exc)
    14            }
    15        })
    16}

    これで撮影処理も完了です!

    takePicture メソッドは3つある

    ちなみに、撮影用の takePicture メソッドは3種類あります。

    1. メモリ内アクセス用に静止画撮影
    2. ファイルに保存
    3. メタデータとファイルに保存

    引数を変更することで選択できるので、適宜使い分けてください。

    さいごに

    今回は、CameraX を使ったプレビューと撮影の実装方法を紹介しました。

    Camera X はとても簡単に実装できるので、カメラ機能を実装したことがない人でも扱いやすい API だと思います。

    また、「基本的なカメラ機能なら CameraX」「手動露出など高度な機能を使いたい時は Camera2API」というように、目的によって使い分けるのが良いでしょう。

    ただ、CameraX はまだベータ版なので、プロダクト導入はまだまだ先になりそうです。

    ベータ版からリリースまでの間にどんな改良がなされるのか、注目の API ですね!

    こちらの記事もオススメ!

    featureImg2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...

    たかやん(エンジニア)

    たかやん(エンジニア)

    おすすめ記事