Android ImageCapture.Builder とヌートリア
cameraX をなかなか粘ってがんばっているなという顔の柴犬です。
桜の開花を追いかけています。やっと一凛咲きました。
概要
cameraX でキャプチャーできましたが、解像度の変更などの設定を WEB で調べてもなかなか分かりませんでした。
WEB を読んでも kotlin言語 の例は多くありましたが JAVA の記事は少なく、WEBでの記事もありましたが下のコードの感じのもので AndroidStudio ではエラーになりコンパイルできませんでした。
PreviewConfig pConfig = new PreviewConfig.Builder().build();
分かるのに結構時間を要しましたので記録します。
1冊だけでは理解の助けにはならないので買い足しました。
2024年2月26日現在
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() がきます。
有効なキャプチャモードは、画質よりも待ち時間を優先する CAPTURE_MODE_MINIMIZE_LATENCY か、待ち時間よりも画質を優先する CAPTURE_MODE_MAXIMIZE_QUALITY です。
設定されていない場合、キャプチャモードのデフォルトは CAPTURE_MODE_MINIMIZE_LATENCY となる。
要求されたフラッシュモード。値はFLASH_MODE_AUTO、FLASH_MODE_ON、FLASH_MODE_SCREEN、またはFLASH_MODE_OFFです。
このエクゼキュータは、takePictureのようなImageCapture専用のIOタスクに使われます。executorが設定されていない場合、IO専用のデフォルトExecutorが代わりに使われます。
要求される出力JPEG画像圧縮品質。値は[1..100]の範囲でなければならず、大きいほど高品質である。
takePictureによって返されるImageProxy、またはtakePictureによって保存される出力JPEG画像に使用されます。
ポストビューが有効かどうか。
FLASH_MODE_SCREENを使用した写真キャプチャに必要なUI側の変更を呼び出し元に通知するScreenFlash。
設定されていない場合、インスタンスはNULLに設定され、ユーザは後でFLASH_MODE_SCREENでsetFlashModeを呼び出す前に設定する必要があります。
非推奨です。代わりに、優先するアスペクト比の設定を指定するには、AspectRatioStrategyを持つResolutionSelectorを使用してください。
希望するImageCaptureのAspectRatio。
アスペクト比は、センサーの向きにおける幅と高さの比です。
設定されているクラスのインスタンスの一意の文字列識別子。
非推奨です。ResolutionStrategyでResolutionSelectorを使用して優先解像度設定を指定します。
サポートされている出力サイズリストから選択するターゲット解像度。
目的のターゲットの回転。
4つの有効な値のうちの1つです: rotation_0、rotation_90、rotation_180、rotation_270。回転の値は、”自然な “回転である ROTATION_0 からの相対値です。
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つ登場してすごいことになっています。
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
setResolutionStrategy の定数
アンロイドのHPの次のWEBに詳しいリファレンスがあります。
https://developer.android.com/reference/androidx/camera/core/resolutionselector/ResolutionStrategy
ヌートリア
今日の柴犬との散歩の途中ではヌートリアに遭遇しました。
目測の距離にして3メートル位でした。結構近くまで相手ヌートルアが寄ってきてくれました。全く人間・柴犬に警戒せず黙々と草を食べていました。
やはり野生の動物ですので刺激せずにこちらから立ち去りました。