Untitled

Untitled

키워드

  1. CameraX
  2. Glide
  3. Content Resolver
  4. ScaleGestureDetector

개발 과정

1. 레이아웃 구현

레이아웃을 구현하기 전에 CameraX 에 대한 의존성을 추가한다.

implementation "androidx.camera:camera-camera2:$camerax_version"
implementation "androidx.camera:camera-lifecycle:$camerax_version"
implementation "androidx.camera:camera-view:$camerax_view_version"

카메라를 통해 찍히는 화면이 보여질 View 를 구현해야 한다. Preview.View 를 통해 이를 구현할 수 있다. 해당 View 가 화면에 꽉차도록 constraintHeight_default 속성을 부여했다.

		<androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/viewFinderContainer"
        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">

        <androidx.camera.view.PreviewView
            android:id="@+id/viewFinder"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:clickable="false"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintDimensionRatio="h, 16:9"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHeight_default="percent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

나머지 버튼에 대한 레이아웃도 구현해준다. imageButton 을 활용하여 구현했다.

		<ImageButton
        android:id="@+id/captureButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:background="@drawable/ic_baseline_camera_24"
        android:backgroundTint="@color/white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <ImageView
        android:id="@+id/thumbnailImageView"
        android:layout_width="60dp"
        android:layout_height="60dp"
        app:layout_constraintBottom_toBottomOf="@id/captureButton"
        app:layout_constraintEnd_toStartOf="@id/captureButton"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@id/captureButton" />

    <ImageButton
        android:id="@+id/flashButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/ic_baseline_flash_on_24"
        android:backgroundTint="@color/white"
        app:layout_constraintBottom_toBottomOf="@+id/captureButton"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/captureButton"
        app:layout_constraintTop_toTopOf="@+id/captureButton" />

2. 권한 요청하기

카메라 역시 사용자에게 직접 권한을 요청 받아야 한다. 항상 구현했던 것처럼 구현했다.

 		private fun requestPermissions() {
        ActivityCompat.requestPermissions(
            this,
            permissions,
            REQUEST_CAMERA_PERMISSION
        )
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

        if (requestCode == REQUEST_CAMERA_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            startCamera(binding.viewFinder)
        }
    }

    companion object {
        private const val REQUEST_CAMERA_PERMISSION = 100
        private val permissions = arrayOf(
            Manifest.permission.CAMERA,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
        )
    }

3. ViewFinder 구현

사용자가 카메라를 통해 촬영할 사진을 미리 볼 수 있도록 ViewFinder 를 구현한다. 간단하게 말하면 위에서 구현한 레이아웃과 연결한다는 의미이다.