CameraXライブラリを使ってカメラアプリケーションを作る

2023年2月25日

これまでに、Android Camera2ライブラリを使ってカメラアプリケーションを作ってきました。当初、カメラアプリケーション需要は小さいと思っていましたが、意外と必要としている人が多いようでアクセスが多いです。そこで、新しいCameraXライブラリでカメラを作ってみます。

1.Android for Developersを利用する

CameraXについては、Googleの開発者向けサイト、Android for Developersで詳しく解説されています。Android for Developersにはサンプルコードも載っていますから、その通りに実装すれば良いのですが、いくつか嵌った点がありましたので、それについて述べたいと思います。

2.build.gradleについて

CameraXライブラリはまだ完成していない?ので、仕様変更が頻繁に起こっています。そのため、ネット上で見つけたCameraXサンプルが動作しないことが頻繁に起こります。

特に、build.gradleで指定するライブラリバージョンが異なると、あちこちでエラーが発生します。バージョンは、以下のページで確認して合わせる必要があります。

私は、安定板リリースを利用しました。以下のように指定して、ようやくエラーが消えました(投稿時点)

    def camerax_version = "1.2.1"

      // CameraX core library
    implementation "androidx.camera:camera-core:$camerax_version"

      // CameraX Camera2 extensions
    implementation "androidx.camera:camera-camera2:$camerax_version"

      // CameraX Lifecycle library
    implementation "androidx.camera:camera-lifecycle:$camerax_version"

      // CameraX View class
    implementation "androidx.camera:camera-view:$camerax_version"

3.プレビューについて

プレビューは、サンプルコードをそのまま利用することで問題なく動作します。しかし、カメラの権限を了承するコードは必要です。これは、以前のCamera2プログラムでも行いました。実装しないと権限なしで落ちてしまいます。

以下のAndroid for Developersのページのコードを加えてください。

また、サンプルではプレビューの表示だけなので問題ないのですが、画像としても保存する場合は、ImageCaptureクラスの指定も必要です。bindToLifecycle関数も、引数を一つ多く指定します。

private ImageCapture imageCapture = null;

imageCapture =
        new ImageCapture.Builder()
                .setTargetRotation(previewView.getDisplay().getRotation())
                .build();

camera = cameraProvider.bindToLifecycle(this, cameraSelector, imageCapture, preview);

なお、画像認識する場合はImageAnalysisクラスも指定しますが、今回は使いません。

4.画像の保存について

画像の保存についてもサンプルソースがありますが、Fileクラスの指定が省略されています。私は、以下のようにしてみました。

private static final String FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS";

File photoFile = new File(getOutputDirectory(),
                     new SimpleDateFormat(FILENAME_FORMAT, Locale.US)
                     .format(System.currentTimeMillis()) + ".jpg") ;

private File getOutputDirectory() {
    File mediaDir = new File(this.getExternalCacheDir(), getResources().getString(R.string.app_name));
    mediaDir.mkdirs();
    String mediaDirS = mediaDir != null ? mediaDir.toString() : "";
    return mediaDir != null && mediaDir.exists() ? mediaDir : getFilesDir();
}

後は、シャッター音を付けたり、写真を撮ったことのポップアップメッセージなどを加えると良いでしょう。

さて、画像の保存されている場所ですが、メディアの登録などを行っていないため、以下のような場所に入っています(環境で変わってくると思います)。

storage/android/data/パッケージ名/cache/アプリケーション名/

の下に入っています。これはファイルマネージャーなどを使わないと辿り着けないので、行方不明になりますね。これは要修正です。

5.CameraXは簡単になったが

Camera2ライブラリではコールバック関数など複雑なコード実装が必要でしたが、CameraXになって随分と簡単になりました。

今回、CameraXのプログラムを作成したのは、ML-Kitを使った画像認識に使うためでした。ML-KitCamera2でも使えますが、複雑なCamera2の実装にさらに複雑なロジックを加えなければならないので、訳が分からなくならないようにCameraXを使いたいと思っています。

しかし、CameraXCamera2に比べて細かい設定ができないという話もあります。純粋なカメラアプリケーションの作成にはCamera2が適しているかもしれません。そんな本格的なプログラムを作成するつもりはありませんが、画像認識を進めていきたいと思います。

created by Rinker
キヤノン
¥319,800 (2024/03/28 19:32:30時点 Amazon調べ-詳細)