앱에 카메라 기능을 추가하려는 경우 CameraX와 Camera2를 사용할 수 있다.
CameraX는 Camera2 패키지를 기반으로 만들어진 Jetpack 라이브러리로, API가 Camera2보다 훨씬 단순하고 기기 호환성 문제가 없어서 안드로이드에서 권장하고 있다.
(Camera2는 복잡한 작업을 할 때 사용한다고 한다.)
CameraX를 사용하여 카메라 화면을 보기 위해서 PreviewView를 사용해야 한다.
PreviewView는 화면을 유연하게(자르기, 크기 조정, 회전 등) 표시할 수 있는 View이다.
카메라 미리보기 예제
CamreaX와 PrevieView를 사용하여 화면에 미리보기를 띄우려고 한다.
1. gradle에 CameraX 의존성 추가
2. 카메라 권한 Manifest에 등록
3. 카메라 권한 체크
4. CameraProvider 요청
5. Preview 생성 및 PreviewView에 연결
CamreaX 의존성 추가
//CameraX
implementation 'androidx.camera:camera-view:1.1.0'
implementation "androidx.camera:camera-camera2:1.2.0-rc01"
implementation 'androidx.camera:camera-lifecycle:1.1.0'
의존성 추가 이후 implementation "androidx.camera:camera-camera2:1.2.0-rc01" 부분에서 빌드에러가 날 수 있는데,
Sdk 버전을 33으로, implementation 'androidx.core:core-ktx:1.9.0' 으로 업데이트하면 빌드된다.
위 버전으로 시도했을 때 계속 안되면 버전을 아래처럼 맞추면 될 것이다.
implementation 'androidx.core:core-ktx:1.7.0'
//CameraX
implementation 'androidx.camera:camera-view:1.1.0'
implementation "androidx.camera:camera-camera2:1.2.0-alpha03"
implementation 'androidx.camera:camera-lifecycle:1.1.0'
카메라 권한 등록
<uses-permission android:name="android.permission.CAMERA"/>
Manifest에 권한을 등록한다.
카메라 권한 체크
/*
* 생략
*/
override fun onCreate(savedInstanceState: Bundle?) {
/*
* 생략
*/
// 카메라 권한 확인
if (allPermissionsGranted()) {
startCamera() // 카메라 실행
} else {
ActivityCompat.requestPermissions(
this, arrayOf(REQUIRED_PERMISSIONS), REQUEST_CODE_PERMISSIONS)
}
}
// 권한 요청 결과를 판단(requestPermissions에 의해 호출)
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, "접근 권한이 허용되지 않아 카메라를 실행할 수 없습니다. 설정에서 접근 권한을 허용해주세요.", Toast.LENGTH_SHORT).show()
}
}
}
// 카메라 권한
private fun allPermissionsGranted() = ContextCompat.checkSelfPermission(
baseContext, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
앱 실행 시 카메라 권한을 체크하여 거절되었을 경우 토스트 팝업을 띄우고, 허용됐다면 미리보기를 띄우는 메서드를 실행하도록 하였다.
CamreaX • PreviewView 적용
1. CameraProvider 요청
2. CameraProvider 사용 가능 여부 확인
3. 카메라를 선택하고 use case를 같이 생명주기에 binding
3-1. Preview 생성(use case)
3-2. 카메라 세팅
3-3. use case와 카메라를 생명 주기에 binding
4. Preview를 PreviewView에 연결
private fun startCamera() {
// 1. CameraProvider 요청
// ProcessCameraProvider는 Camera의 생명주기를 LifeCycleOwner의 생명주기에 Binding 함
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
// 2. CameraProvier 사용 가능 여부 확인
// 생명주기에 binding 할 수 있는 ProcessCameraProvider 객체 가져옴
val cameraProvider = cameraProviderFuture.get()
// 3. 카메라를 선택하고 use case를 같이 생명주기에 binding
// 3-1. Preview를 생성 → Preview를 통해서 카메라 미리보기 화면을 구현.
// surfaceProvider는 데이터를 받을 준비가 되었다는 신호를 카메라에게 보내준다.
// setSurfaceProvider는 PreviewView에 SurfaceProvider를 제공해준다.
val preview = Preview.Builder().build()
preview.setSurfaceProvider(mBinding.viewFinder.surfaceProvider)
// 아래처럼 써도 됨
// val preview = Preview.Builder().build().also {
// it.setSurfaceProvider(mBinding.viewFinder.surfaceProvider)
// }
// 3-2. 카메라 세팅
// CameraSelector는 카메라 세팅을 맡는다.(전면, 후면 카메라)
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
try {
// binding 전에 binding 초기화
cameraProvider.unbindAll()
// 3-3. use case와 카메라를 생명 주기에 binding
camera = cameraProvider.bindToLifecycle(
this, cameraSelector, preview)
cameraController = camera!!.cameraControl
cameraController!!.setZoomRatio(1F) // 1x Zoom
} catch (exc: Exception) {
println("에러 $exc")
}
// 4. Preview를 PreviewView에 연결한다.
// surfaceProvider는 데이터를 받을 준비가 되었다는 신호를 카메라에게 보내준다.
// setSurfaceProvider는 PreviewView에 SurfaceProvider를 제공해준다.
preview.setSurfaceProvider(mBinding.viewFinder.surfaceProvider)
}, ContextCompat.getMainExecutor(this))
}
'Android > Camera' 카테고리의 다른 글
[Android] 카메라 캡처(촬영)하기 - CameraX ˙ ImageCapture (0) | 2022.11.14 |
---|
댓글