やりたいこと
CaptureRequest.Builderの機能を使って、カメラの露光感度などを設定した状態でプレビューを表示したいです。
前提
設定方法を調べると、CaptureRequestクラスのset()メソッドを使用して
set(CaptureRequest.SENSOR_EXPOSURE_TIME, シャッタースピードの値)
set(CaptureRequest.SENSOR_SENSITIVITY, 露光感度の値)
とすることで設定できることがわかりました。
【公式リファレンス】
また、リファレンスでは、「CONTROL_MODEをOFFにすること」が条件として書かれておりましたので、
set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF)
としてモードをOFFに設定しています。
やったこと
リファレンスをもとにカメラのプレビューを表示するコードを記述しました。
kotlin
1/* MainActivity.kt */ 2 3package com.example.mycamera2application2 4 5import android.Manifest 6import android.content.Context 7import android.content.pm.PackageManager 8import android.graphics.SurfaceTexture 9import android.hardware.camera2.CameraCaptureSession 10import android.hardware.camera2.CameraDevice 11import android.hardware.camera2.CameraManager 12import android.hardware.camera2.CaptureRequest 13import androidx.appcompat.app.AppCompatActivity 14import android.os.Bundle 15import android.view.Surface 16import android.view.TextureView 17import androidx.core.app.ActivityCompat 18import androidx.core.content.ContextCompat 19 20class MainActivity : AppCompatActivity() { 21 override fun onCreate(savedInstanceState: Bundle?) { 22 super.onCreate(savedInstanceState) 23 setContentView(R.layout.activity_main) 24 } 25 // 定数を定義 26 companion object { 27 private const val REQUEST_CODE_PERMISSIONS = 10 28 private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA) 29 } 30 // 変数を定義 31 private lateinit var previewRequestBuilder : CaptureRequest.Builder 32 private val textureView: TextureView by lazy { 33 findViewById(R.id.textureView) 34 } 35 36 override fun onResume() { 37 super.onResume() 38 // ビューの準備ができている場合 39 if (textureView.isAvailable) { 40 // カメラ起動用関数を実行 41 openCamera() 42 } else { 43 // ビューにイベントリスナーを設定 44 textureView.surfaceTextureListener = object : TextureView.SurfaceTextureListener { 45 override fun onSurfaceTextureAvailable(p0: SurfaceTexture, p1: Int, p2: Int) { 46 openCamera() 47 } 48 // ビューのサイズが変更された際の処理 49 override fun onSurfaceTextureSizeChanged(p0: SurfaceTexture, p1: Int, p2: Int) {} 50 // ビューが更新された際の処理 51 override fun onSurfaceTextureUpdated(p0: SurfaceTexture) {} 52 // ビューが破棄された際の処理 53 override fun onSurfaceTextureDestroyed(p0: SurfaceTexture): Boolean = true 54 } 55 } 56 } 57 private var cameraDevice: CameraDevice? = null 58 private val cameraManager: CameraManager by lazy { 59 getSystemService(Context.CAMERA_SERVICE) as CameraManager 60 } 61 // 全てのパーミッションの使用許諾を取得 62 private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all { 63 ContextCompat.checkSelfPermission( 64 baseContext, it) == PackageManager.PERMISSION_GRANTED 65 } 66 67 68 private fun openCamera() { 69 // カメラの使用許可を取得する 70 if (allPermissionsGranted()) { 71 if (ActivityCompat.checkSelfPermission( 72 this, 73 Manifest.permission.CAMERA 74 ) != PackageManager.PERMISSION_GRANTED 75 ) { 76 return 77 } 78 cameraManager.openCamera("0", object: CameraDevice.StateCallback() { 79 // カメラが起動できた場合 80 override fun onOpened(camera: CameraDevice) { 81 cameraDevice = camera 82 createCameraPreviewSession() 83 } 84 // カメラから切断された場合 85 override fun onDisconnected(camera: CameraDevice) { 86 cameraDevice?.close() 87 cameraDevice = null 88 } 89 // カメラの接続でエラーが発生した場合 90 override fun onError(camera: CameraDevice, p1: Int) { 91 cameraDevice?.close() 92 cameraDevice = null 93 } 94 }, null) 95 } else { 96 ActivityCompat.requestPermissions( 97 this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS 98 ) 99 } 100 } 101 102 private fun configCamera(){ 103 // カメラのモード設定 104 previewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF) 105 previewRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CaptureRequest.CONTROL_CAPTURE_INTENT_CUSTOM) 106 // iso,シャッタースピードなどの調整 107 previewRequestBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, 1) // シャッタスピード 108 previewRequestBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, 1) // iso 109 } 110 111 private var captureSession: CameraCaptureSession? = null 112 113 // プレビュー用のセッションを作成 114 private fun createCameraPreviewSession() { 115 if (cameraDevice == null) { 116 return 117 } 118 val texture = textureView.surfaceTexture 119 // プレビューのサイズを指定 120 texture?.setDefaultBufferSize(640, 480) 121 // プレビューの表示先となるsurfaceを設定 122 val surface = Surface(texture) 123 124 previewRequestBuilder = cameraDevice!!.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW) 125 // カメラのモード設定と値の設定 126 configCamera() 127 previewRequestBuilder.addTarget(surface) 128 129 cameraDevice?.createCaptureSession(listOf(surface), object : CameraCaptureSession.StateCallback() { 130 // セッションが取得できた場合 131 override fun onConfigured(session: CameraCaptureSession) { 132 captureSession = session 133 // プレビュー画像をTextureViewにセット 134 captureSession?.setRepeatingRequest(previewRequestBuilder.build(), null, null) 135 } 136 // セッションが取得できなかった場合 137 override fun onConfigureFailed(session: CameraCaptureSession) {} 138 }, null) 139 } 140}
kotlin
1/* activity_main.xml */ 2 3<?xml version="1.0" encoding="utf-8"?> 4<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 5 xmlns:app="http://schemas.android.com/apk/res-auto" 6 xmlns:tools="http://schemas.android.com/tools" 7 android:layout_width="match_parent" 8 android:layout_height="match_parent" 9 tools:context=".MainActivity"> 10 11 <TextureView 12 android:id="@+id/textureView" 13 android:layout_width="match_parent" 14 android:layout_height="match_parent" 15 tools:layout_editor_absoluteX="154dp" 16 tools:layout_editor_absoluteY="296dp" /> 17 18</androidx.constraintlayout.widget.ConstraintLayout> 19
その他エラー
セッションを取得するために「createCaptureSession()」を使用しているのですが、非推奨であると警告が表示されています。
わからないこと
カメラをプレビューすることはできていますが、露光感度を設定するために「CONTROL_MODEをOFFにする」とプレビューが表示されなくなってしまいます。露光感度の設定を行う場合の記述方法が分からないので教えていただきたいです。。
また、「createCaptureSession()」に代わる推奨記述方法を調査したのですが分からないので、そちらも教えていただけますと幸いです。。
内容が分かりづらい場合や、情報が不足していると感じられた場合はコメントにてご指摘いただけますと幸いです。
あなたの回答
tips
プレビュー