1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Android】CameraXで写真撮影

Last updated at Posted at 2023-02-26

はじめに

以前の記事でCameraXの導入について解説したが、CameraXでの写真撮影の方法について解説。

ライブラリの導入

build.gradle(:app)に以下のライブラリを追加

build.gradle
	implementation 'androidx.camera:camera-core:1.2.1'
	implementation 'androidx.camera:camera-camera2:1.2.1'
	implementation 'androidx.camera:camera-lifecycle:1.2.1'
	implementation 'androidx.camera:camera-view:1.2.1'

カメラパーミッションの使用

マニフェストファイルにカメラを使用することを宣言。

AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA"/>

レイアウト作成

PreviewViewを使用してカメラ映像を表示。撮影用ボタンも追加。

activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:app="http://schemas.android.com/apk/res-auto"
	android:id="@+id/camera_container"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:background="@android:color/black">

	<androidx.camera.view.PreviewView
		android:id="@+id/view_finder"
		android:layout_width="0dp"
		android:layout_height="0dp"
		app:layout_constraintBottom_toBottomOf="parent"
		app:layout_constraintEnd_toEndOf="parent"
		app:layout_constraintStart_toStartOf="parent"
		app:layout_constraintTop_toTopOf="parent"/>

	<Button
		android:id="@+id/shutter_button"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:text="shutter"
		app:layout_constraintBottom_toBottomOf="parent"
		app:layout_constraintEnd_toEndOf="parent"
		app:layout_constraintStart_toStartOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

処理部分

takePictureメソッドで写真撮影処理を行っている。

MainActivity.kt
class MainActivity : AppCompatActivity() {

	companion object {
		private const val REQUEST_CODE_PERMISSIONS = 10
		private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
	}

	private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }

	private val imageCapture: ImageCapture by lazy {
		ImageCapture.Builder().setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY).build()
	}

	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(binding.root)

		if (allPermissionsGranted()) {
			startCamera()
		} else {
			ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)
		}

		binding.shutterButton.setOnClickListener {
			takePicture()
		}
	}

	override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
		super.onRequestPermissionsResult(requestCode, permissions, grantResults)
		if (requestCode == REQUEST_CODE_PERMISSIONS) {
			if (allPermissionsGranted()) {
				startCamera()
			} else {
				Toast.makeText(this, "Permissions not granted by the user.", Toast.LENGTH_SHORT).show()
				finish()
			}
		}
	}

	private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
		ContextCompat.checkSelfPermission(baseContext, it) == PackageManager.PERMISSION_GRANTED
	}

	private fun startCamera() {
		val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
		cameraProviderFuture.addListener({ bindPreview(cameraProviderFuture.get()) }, ContextCompat.getMainExecutor(this))
	}

	private fun bindPreview(cameraProvider: ProcessCameraProvider) {
		val preview = Preview.Builder().build()
		val cameraSelector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build()
		preview.setSurfaceProvider(binding.viewFinder.surfaceProvider)
		cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, preview, imageCapture)
	}

	private fun takePicture() {
		val contentValues = ContentValues()
		contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, SimpleDateFormat("yyyyMMddHHmmss").format(Date()) + ".jpg")
		contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")

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

		imageCapture.takePicture(
			outputFileOptions,
			ContextCompat.getMainExecutor(this),
			object : ImageCapture.OnImageSavedCallback {
				override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
					Toast.makeText(this@MainActivity, "success", Toast.LENGTH_LONG).show()
				}

				override fun onError(error: ImageCaptureException) {
					Toast.makeText(this@MainActivity, "error", Toast.LENGTH_LONG).show()
				}
			})
	}
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?