Sibainu Relax Room

柴犬と過ごす

Android ImageCapture.Builder とヌートリア

cameraX をなかなか粘ってがんばっているなという顔の柴犬です。

桜の開花を追いかけています。やっと一凛咲きました。

概要

cameraX でキャプチャーできましたが、解像度の変更などの設定を WEB で調べてもなかなか分かりませんでした。

WEB を読んでも kotlin言語 の例は多くありましたが JAVA の記事は少なく、WEBでの記事もありましたが下のコードの感じのもので AndroidStudio ではエラーになりコンパイルできませんでした。

 PreviewConfig pConfig = new PreviewConfig.Builder().build();

分かるのに結構時間を要しましたので記録します。

1冊だけでは理解の助けにはならないので買い足しました。

WEBのみでは断片的で覚えにくいので最初に購入した Kotlin の本です。

cameraXのキャプチャー設定

アンロイドのHPの次の WEB に詳しいリファレンスがあります。

https://developer.android.com/reference/androidx/camera/core/ImageCapture.Builder

当初、使い方が分からずいろいろ試行錯誤してみました。

                // イメージキャプチャーを受け取るオブジェクト
                imagecapture = new ImageCapture.Builder()
                        .setTargetResolution(new Size(640,480))
                        .setTargetRotation(Surface.ROTATION_0)
                        .setJpegQuality(50)
                        .build();

上のようにメソッドチェーンで繋いで、最後 build()を実行して完結という形にしてうまくいきました。

startCamera

設定を変更しましたので、記録します。

copy

    private void startCamera() {
        ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);

        cameraProviderFuture.addListener(() -> {
            try {
                // カメラのライフサイクルをアプリのライフサイクルに紐づけ
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();

                // プレビューの設定
                PreviewView previewView = findViewById(R.id.viewFinder);
                Preview preview = new Preview.Builder().build();
                preview.setSurfaceProvider(previewView.getSurfaceProvider());

                // イメージキャプチャーを受け取るオブジェクト
                imagecapture = new ImageCapture.Builder()
                        .setTargetResolution(new Size(640,480))
                        .setTargetRotation(Surface.ROTATION_0)
                        .setJpegQuality(50)
                        .build();

                // 背面カメラをデフォルト
                CameraSelector cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;

                // 既存の廃棄
                cameraProvider.unbindAll();

                // カメラをビュー・イメージキャプチャーに紐づけ
                cameraProvider.bindToLifecycle(this, cameraSelector, preview, imagecapture);

            } catch (ExecutionException | InterruptedException e) {
                Log.e(TAG, e.getLocalizedMessage(), e);
            }
        }, ContextCompat.getMainExecutor(this));
    }

ImageCapture.Builder メソッドまとめ

各メソッドの戻り値が build を除きすべて ImageCapture.Builder になっていますのでメソッドチェーンで繋ぐことができると理解できます。やはりリファレンスを読まないといけないと反省です。で最後に確定の build() がきます。

 
メソッド
内容
パラメータ等
戻り値
build
現在の状態から不変のImageCaptureをビルドします。
 
Null ではない ImageCapture
setCaptureMode
画像キャプチャモードを設定します。
int captureMode
有効なキャプチャモードは、画質よりも待ち時間を優先する CAPTURE_MODE_MINIMIZE_LATENCY か、待ち時間よりも画質を優先する CAPTURE_MODE_MAXIMIZE_QUALITY です。
設定されていない場合、キャプチャモードのデフォルトは CAPTURE_MODE_MINIMIZE_LATENCY となる。
Null ではない ImageCapture.Builder
setFlashMode
フラッシュモードを設定します。
int flashMode
要求されたフラッシュモード。値はFLASH_MODE_AUTO、FLASH_MODE_ON、FLASH_MODE_SCREEN、またはFLASH_MODE_OFFです。
Null ではない ImageCapture.Builder
setIoExecutor
IOタスクに使われるデフォルトのエクゼキュータを設定します。
IOタスクに使用されるエクゼキュータ。
このエクゼキュータは、takePictureのようなImageCapture専用のIOタスクに使われます。executorが設定されていない場合、IO専用のデフォルトExecutorが代わりに使われます。
Null ではない ImageCapture.Builder
setJpegQuality
出力JPEG画像の圧縮品質を設定します。
intRange(from = 1, to = 100) int jpegQuality
要求される出力JPEG画像圧縮品質。値は[1..100]の範囲でなければならず、大きいほど高品質である。
takePictureによって返されるImageProxy、またはtakePictureによって保存される出力JPEG画像に使用されます。
Null ではない ImageCapture.Builder
setPostviewEnabled
ポストビュー画像の生成を有効にします。ポストビュー画像は、画像キャプチャ中に最終的な高画質画像よりも早い段階で生成される低画質画像で、最終画像の準備が整うまでサムネイルやプレースホルダとして使用できます。
boolean postviewEnabled
ポストビューが有効かどうか。
Null ではない ImageCapture.Builder
setPostviewResolutionSelector
利用可能なポストビューサイズからポストビューサイズを選択するResolutionSelectorを設定します。
これらの利用可能なポストビューサイズは、ImageCaptureサイズより小さいか等しい。androidx.camera.core.resolutionselector.ResolutionFilterを実装し、ResolutionSelectorに設定することで、利用可能なサイズのリストを取得し、使用するサイズを決定することができます。
Null ではない ImageCapture.Builder
setResolutionSelector
サポートされている優先解像度を選択する解像度セレクタを設定します。
ImageCapture のデフォルトの解像度ストラテジーは HIGHEST_AVAILABLE_STRATEGY で、使用可能な最大解像度が選択されます。アプリケーションは、異なる解像度戦略でこのデフォルト戦略をオーバーライドできます。
Null ではない ImageCapture.Builder
setScreenFlash
スクリーンフラッシュ操作に必要なScreenFlashインスタンスを設定します。
Null以外のImageCapture.ScreenFlash screenFlash
FLASH_MODE_SCREENを使用した写真キャプチャに必要なUI側の変更を呼び出し元に通知するScreenFlash。
設定されていない場合、インスタンスはNULLに設定され、ユーザは後でFLASH_MODE_SCREENでsetFlashModeを呼び出す前に設定する必要があります。
Null以外のImageCapture.Builderを返します。
setTargetAspectRatio
この設定からの画像について、意図するターゲットのアスペクト比を設定します。
非推奨です。代わりに、優先するアスペクト比の設定を指定するには、AspectRatioStrategyを持つResolutionSelectorを使用してください。
int アスペクト比
希望するImageCaptureのAspectRatio。
アスペクト比は、センサーの向きにおける幅と高さの比です。
Null ではない ImageCapture.Builder
setTargetName
設定中のターゲットオブジェクトの名前を設定します。
Null 以外の文字列 targetName
設定されているクラスのインスタンスの一意の文字列識別子。
Null ではない ImageCapture.Builder
setTargetResolution
目的の出力ターゲット解像度を設定します。
非推奨です。ResolutionStrategyでResolutionSelectorを使用して優先解像度設定を指定します。
Null以外のサイズ解像度
サポートされている出力サイズリストから選択するターゲット解像度。
Null ではない ImageCapture.Builder
setTargetRotation
この設定からの画像に対して、意図したターゲットの回転を設定します。
int rotation
目的のターゲットの回転。
4つの有効な値のうちの1つです: rotation_0、rotation_90、rotation_180、rotation_270。回転の値は、”自然な “回転である ROTATION_0 からの相対値です。
Null ではない ImageCapture.Builder
 
計 13要素
 

setTargetResolution が非推奨になっています。ResolutionStrategyでResolutionSelectorを使用してとありますがどうしたらいいのでしょうか。

私が試した方法を記録します。

setTargetResolution が非推奨 どうする

上の startCamera の中の次の部分を

     imagecapture = new ImageCapture.Builder()
                        .setTargetResolution(new Size(640,480))
                        .setTargetRotation(Surface.ROTATION_90)
                        .setJpegQuality(60)
                        .build();

setResolutionSelector を使ってこのように変えればいいようです。

     imagecapture = new ImageCapture.Builder()
                        //.setTargetResolution(new Size(640,480))
                        .setResolutionSelector(
                                new ResolutionSelector.Builder()
                                        .setResolutionStrategy(
                                                new ResolutionStrategy(new Size(640, 480),
             ResolutionStrategy.FALLBACK_RULE_CLOSEST_LOWER_THEN_HIGHER))
                                        .build()
                        )
                        .setTargetRotation(Surface.ROTATION_90)
                        .setJpegQuality(60)
                        .build();

setResolutionSelector の中に new が3つ登場してすごいことになっています。

copy

    private void startCamera() {
        ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);

        cameraProviderFuture.addListener(() -> {
            try {
                // カメラのライフサイクルをアプリのライフサイクルに紐づけ
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();

                // プレビューの設定
                PreviewView previewView = findViewById(R.id.viewFinder);
                Preview preview = new Preview.Builder().build();
                preview.setSurfaceProvider(previewView.getSurfaceProvider());

                // イメージキャプチャーを受け取るオブジェクト
                imagecapture = new ImageCapture.Builder()
                        //.setTargetResolution(new Size(640,480))
                        .setResolutionSelector(
                                new ResolutionSelector.Builder()
                                        .setResolutionStrategy(
                                                new ResolutionStrategy(new Size(640, 480),
                                                                       ResolutionStrategy.FALLBACK_RULE_CLOSEST_LOWER_THEN_HIGHER))
                                        .build()
                        )
                        .setTargetRotation(Surface.ROTATION_90)
                        .setJpegQuality(60)
                        .build();

                // 背面カメラをデフォルト
                CameraSelector cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;

                // 既存の廃棄
                cameraProvider.unbindAll();

                // カメラをビュー・イメージキャプチャーに紐づけ
                cameraProvider.bindToLifecycle(this, cameraSelector, preview, imagecapture);

            } catch (ExecutionException | InterruptedException e) {
                Log.e(TAG, e.getLocalizedMessage(), e);
            }
        }, ContextCompat.getMainExecutor(this));
    }

setResolutionSelector のメソッド

アンロイドのHPの次のWEBに詳しいリファレンスがあります。

https://developer.android.com/reference/androidx/camera/core/resolutionselector/ResolutionSelector
 
メソッド
内容
パラメータ等
戻り値
build()
解像度セレクタを構築する。
 
Null ではない ResolutionSelector
setAllowedResolutionMode()
許可される解像度モードを設定します。
int mode
Null ではない ResolutionSelector.Builder
setAspectRatioStrategy()
UseCaseのアスペクト比選択ストラテジーを設定します。
Null ではない AspectRatioStrategy aspectRatioStrategy
Null ではない ResolutionSelector.Builder
setResolutionFilter()
最終的な希望サイズリストを出力する解像度フィルタを設定する。
Null ではない ResolutionFilter resolutionFilter
Null ではない ResolutionSelector.Builder
setResolutionStrategy()
UseCase の解像度選択ストラテジーを設定します。
Null ではない ResolutionStrategy resolutionStrategy
Null ではない ResolutionSelector.Builder
 
計 5要素
 

setResolutionStrategy の定数

アンロイドのHPの次のWEBに詳しいリファレンスがあります。

https://developer.android.com/reference/androidx/camera/core/resolutionselector/ResolutionStrategy
 
定数
内容
FALLBACK_RULE_CLOSEST_HIGHER = 2
指定されたバインドサイズが利用できない場合、CameraXは最も近い高解像度サイズにフォールバックします。
static final int
FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER = 1
指定されたバインドサイズが利用できない場合、CameraXは最も近い高解像度サイズにフォールバックします。
static final int
FALLBACK_RULE_CLOSEST_LOWER = 4
指定されたバインドサイズが利用できない場合、CameraXは最も近い低解像度サイズにフォールバックします。
static final int
FALLBACK_RULE_CLOSEST_LOWER_THEN_HIGHER = 3
指定されたバインドサイズが利用できない場合、CameraXは、最も近い低解像度サイズを選択します。
static final int
FALLBACK_RULE_NONE = 0
CameraXは、指定されたバインドサイズが利用できない場合、代替サイズを選択しない。
static final int
HIGHEST_AVAILABLE_STRATEGY
解像度ストラテジーは、利用可能な最も高い解像度を選択します。
static final @NonNull ResolutionStrategy
 
計 6要素
 

ヌートリア

今日の柴犬との散歩の途中ではヌートリアに遭遇しました。

目測の距離にして3メートル位でした。結構近くまで相手ヌートルアが寄ってきてくれました。全く人間・柴犬に警戒せず黙々と草を食べていました。

やはり野生の動物ですので刺激せずにこちらから立ち去りました。