📸

【Android】CameraXを使用した写真撮影

2024/04/13に公開

AndroidでCameraXを使用した写真撮影の完全ガイド

Androidの開発において、カメラ機能は多くのアプリケーションで不可欠な部分です。CameraXは、Android Jetpackの一部として提供されるカメラAPIのラッパーであり、開発者が容易にカメラ機能をアプリケーションに統合できるように設計されています。この記事では、CameraXを使用して写真を撮影する基本的なプロセスを説明します。

CameraXの基本

CameraXは、複数のAndroidデバイスにわたるカメラ操作の簡素化と統一を目指したライブラリです。プレビュー、写真撮影、ビデオ録画など、カメラに関連する一般的な機能を容易に実装できるようにします。

必要な権限の設定

CameraXを使用する前に、アプリのAndroidManifest.xmlファイルに以下の権限を追加する必要があります。

<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera.any"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

startCameraメソッドの実装

startCameraメソッドでは、カメラのプレビューをアプリケーションのUIに表示します。このメソッドは、CameraXライブラリのProcessCameraProviderを使用して、カメラのライフサイクルをアプリケーションのライフサイクルにバインドします。

private fun startCamera() {
    val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
    cameraProviderFuture.addListener({
        val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
        val preview = Preview.Builder().build().also {
            it.setSurfaceProvider(viewBinding.viewFinder.surfaceProvider)
        }
        imageCapture = ImageCapture.Builder().build()
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

        try {
            cameraProvider.unbindAll()
            cameraProvider.bindToLifecycle(
                this, cameraSelector, preview, imageCapture)
        } catch(exc: Exception) {
            Log.e(TAG, "Use case binding failed", exc)
        }
    }, ContextCompat.getMainExecutor(this))
}

takePhotoメソッドの実装

takePhotoメソッドでは、実際に写真を撮影し、デバイスのストレージに保存します。ImageCaptureクラスのtakePictureメソッドを使用して、写真の撮影と保存を行います。

private fun takePhoto() {
    val imageCapture = imageCapture ?: return

    val name = SimpleDateFormat(FILENAME_FORMAT, Locale.US).format(System.currentTimeMillis())
    val contentValues = ContentValues().apply {
        put(MediaStore.MediaColumns.DISPLAY_NAME, name)
        put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
        if(Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
            put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/CameraX-Image")
        }
    }

    val outputOptions = ImageCapture.OutputFileOptions.Builder(
        contentResolver, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues).build()

    imageCapture.takePicture(
        outputOptions, ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageSavedCallback {
            override fun onError(exc: ImageCaptureException) {
                Log.e(TAG, "Photo capture failed: ${exc.message}", exc)
            }

            override fun onImageSaved(output: ImageCapture.OutputFileResults){
                val msg = "Photo capture succeeded: ${output.savedUri}"
                Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
                Log.d(TAG, msg)
           

 }
        })
}

Discussion