Slide 1

Slide 1 text

CameraX を使ってみた 関西モバイルアプリ研究会 A #4 @takuji31

Slide 2

Slide 2 text

自己紹介 西林 拓志 (にしばやし たくじ ) Twitter/GitHub takuji31 Sansan 株式会社 技術本部 Mobile Application グループ Eight Android テックリード Android (2009〜 ) Kotlin (2014〜 ) 1

Slide 3

Slide 3 text

スマートフォンのカメラ使ってますか? 2

Slide 4

Slide 4 text

今年で世界初のカメラ付き携帯電話が発売されて 25(!)年 3

Slide 5

Slide 5 text

スマートフォンにも当たり前のようにカメラがついてます ね 4

Slide 6

Slide 6 text

アプリ開発者ならスマートフォンのカメラで遊びたいはず 5

Slide 7

Slide 7 text

CameraX 6

Slide 8

Slide 8 text

Jetpack の一つでカメラを扱うライブラリー 7

Slide 9

Slide 9 text

幅広いデバイスをサポート 8

Slide 10

Slide 10 text

拡張機能(ボケ、 HDR、夜間モード等)に対応 9

Slide 11

Slide 11 text

API 21 から使える 10

Slide 12

Slide 12 text

セットアップ 11

Slide 13

Slide 13 text

libs.versions.toml [versions] camerax = "1.4.0-beta02" [libraries] androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "camerax" } androidx-camera-lifecycle = { module = "androidx.camera:camera-lifecycle", version.ref = "camerax" } androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "camerax" } androidx-camera-extensions = { module = "androidx.camera:camera-extensions", version.ref = "camerax" } 12

Slide 14

Slide 14 text

build.gradle.kts dependencies { implementation(libs.androidx.camera.camera2) implementation(libs.androidx.camera.lifecycle) implementation(libs.androidx.camera.view) implementation(libs.androidx.camera.extensions) } 13

Slide 15

Slide 15 text

使い方 14

Slide 16

Slide 16 text

使い方 val controller = LifecycleCameraController(this) controller.bindToLifecycle(this) controller.cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA setContent { AndroidView( factory = { context -> PreviewView(context).apply { layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) setController(controller) } }, onRelease = { controller.unbind() } ) } 15

Slide 17

Slide 17 text

16

Slide 18

Slide 18 text

カメラ切り替え 17

Slide 19

Slide 19 text

カメラ切り替え val cameraSelector = if (controller.cameraSelector == CameraSelector.DEFAULT_BACK_CAMERA) { CameraSelector.DEFAULT_FRONT_CAMERA } else { CameraSelector.DEFAULT_BACK_CAMERA } controller.cameraSelector = cameraSelector 18

Slide 20

Slide 20 text

撮影 19

Slide 21

Slide 21 text

撮影 val values = ContentValues().apply { put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") } val imageUri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values) controller.takePicture( ImageCapture .OutputFileOptions .Builder( contentResolver.openOutputStream(imageUri!!)!! ).build(), ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageSavedCallback { override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) { Toast.makeText(this, "Image captured", Toast.LENGTH_SHORT).show() } override fun onError(exception: ImageCaptureException) { Toast.makeText(this, "Image capture failed", Toast.LENGTH_SHORT).show() } }) 20

Slide 22

Slide 22 text

拡張機能 21

Slide 23

Slide 23 text

ボケ、 HDR、夜間モード等デフォルト以外の機能 22

Slide 24

Slide 24 text

拡張機能 val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA val mainExecutor = ContextCompat.getMainExecutor(this) val cameraProviderFuture = ProcessCameraProvider.getInstance(this) val imageCapture = ImageCapture.Builder().build() val preview = CameraXPreview.Builder().build() 23

Slide 25

Slide 25 text

拡張機能 cameraProviderFuture.addListener({ val cameraProvider = cameraProviderFuture.get() val extensionsManagerFuture = ExtensionsManager.getInstanceAsync(this@MainActivity, cameraProvider) //... }, mainExecutor) 24

Slide 26

Slide 26 text

拡張機能 extensionsManagerFuture.addListener({ val extensionsManager = extensionsManagerFuture.get() if (extensionsManager.isExtensionAvailable(cameraSelector, ExtensionMode.NIGHT)) { val newSelector = extensionsManager.getExtensionEnabledCameraSelector( cameraSelector, ExtensionMode.NIGHT ) preview.surfaceProvider = findViewById(R.id.previewView).surfaceProvider cameraProvider.bindToLifecycle(this, newSelector, imageCapture, preview) } }, mainExecutor) 25

Slide 27

Slide 27 text

Pixel 8 Pro で試してみた 26

Slide 28

Slide 28 text

BOKEH 27

Slide 29

Slide 29 text

HDR 28

Slide 30

Slide 30 text

NIGHT 29

Slide 31

Slide 31 text

他にも MLKit と統合して QR コードスキャナーを作った りできるっぽい 30

Slide 32

Slide 32 text

https://github.com/android/camera-samples 31

Slide 33

Slide 33 text

Thank you 32