안드로이드 앱에서 카메라 기능은 자주 사용되는 중요한 요소 중 하나입니다.
이번 글에서는 CameraX 라이브러리에 대해서 간략하게 살펴보고,
CameraX를 활용하여 사진 촬영, 이미지 저장, 이미지 결과까지 확인하는 카메라 프리뷰 예제를 살펴보려고 합니다.
해당 예제를 통해서 Android Jetpack의 CameraX 라이브러리를 효과적으로 사용하는 방법을 확인할 수 있습니다.
혹시 카메라 프리뷰 예제를 실행하고 싶으시다면 아래 링크를 통해 다운로드가 가능합니다.
안드로이드 CameraX 라이브러리
CameraX는 Android Jetpack의 일부로 안드로이드 앱에서 카메라 기능을 간단하고 효율적으로 구현할 수 있도록 설계된 라이브러리입니다. 기존의 Camera API는 다소 복잡한 설정과 디바이스 호환성 문제를 가지고 있습니다. CameraX는 이러한 문제를 해결하며 안드로이드 카메라 개발을 쉽게 만드는 강력한 도구입니다. 카메라 기능을 구현해야 된다면 CameraX 라이브러리를 사용하는 걸 추천드립니다.
항목 | Camera API | CameraX |
출시 시기 | 2008년 | 2019년 |
API 복잡성 | 다소 복잡하고 낮은 수준의 API 제공 | 사용자 친화적인 고수준 API 제공 |
미래 지향성 | 유지보수 종료, 업데이트 없음 | Jetpack으로 지속적인 업데이트 제공 |
호환성 | 디바이스마다 동작이 달라지기도 함 | CameraX 내부적으로 호환성 처리 |
생명주기 | 직접 생명주기 관래해야함 | Activity 또는 Fragment와 자동으로 연동 |
안드로이드 CameraX 라이브러리 추가
gradle에 아래와 같이 cameraX 라이브러리를 추가합니다.
dependencies {
....
// CameraX
implementation("androidx.camera:camera-core:1.4.0")
implementation("androidx.camera:camera-camera2:1.4.0")
implementation("androidx.camera:camera-lifecycle:1.4.0")
implementation("androidx.camera:camera-view:1.4.0")
implementation("androidx.camera:camera-extensions:1.4.0")
}
안드로이드 CameraX 권한 승인
AndroidManifest.xml에 CAMERA 권한을 추가하고,
<uses-permission android:name="android.permission.CAMERA" />
러닝타임에 CAMERA 권한 승인 요청하는 동작을 작성합니다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
requestCameraPermission()
}
private fun requestCameraPermission() {
val permissions = arrayOf(Manifest.permission.CAMERA)
ActivityCompat.requestPermissions(this, permissions, 10)
}
}
안드로이드 카메라 프리뷰 예제: MainActivity
카메라 프리뷰 MainActivity 실행화면 및 소스코드는 아래와 같습니다.
CAMERA PREVIEW 버튼을 통해서 카메라 프리뷰를 진입하고, 이미지 결과를 보여주는 화면으로 구성되어 있습니다.
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val cameraPreviewLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
val imageUri = result.data?.getStringExtra("imageUri")
imageUri?.let {
binding.ivResult.setImageURI(null)
binding.ivResult.setImageURI(Uri.parse(it))
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.btnCameraPreview.setOnClickListener {
val intent = Intent(this, CameraActivity::class.java)
cameraPreviewLauncher.launch(intent)
}
requestCameraPermission()
}
private fun requestCameraPermission() {
val permissions = arrayOf(Manifest.permission.CAMERA)
ActivityCompat.requestPermissions(this, permissions, 10)
}
}
안드로이드 카메라 프리뷰 예제: CameraActivity
카메라 프리뷰 예제에서 CameraActivity 실행화면 및 소스코도는 아래와 같습니다.
카메라 프리뷰 영역과 사진촬영, 플래시 On/Off, 화면전환 Front/Back 버튼으로 기본적인 기능을 포함하고 있습니다.
class CameraActivity : AppCompatActivity() {
private lateinit var binding: ActivityCameraPreviewBinding
private lateinit var cameraProvider: ProcessCameraProvider
private lateinit var cameraControl: CameraControl
private lateinit var cameraInfo: CameraInfo
// UseCase
private var preview: Preview? = null
private var imageCapture: ImageCapture? = null
// Camera State
private var isFlashOn = false
private var isFrontCamera = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_camera_preview)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
startCamera()
setListeners()
}
private fun startCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
cameraProvider = cameraProviderFuture.get()
try {
bindCameraUseCases()
} catch (e: Exception) {
Log.e("CameraX", "카메라 시작 실패", e)
}
}, ContextCompat.getMainExecutor(this))
}
private fun bindCameraUseCases() {
preview = Preview.Builder().build().apply {
surfaceProvider = binding.cameraPreview.surfaceProvider
}
imageCapture = ImageCapture.Builder()
.setTargetRotation(binding.cameraPreview.display.rotation)
.build()
val cameraSelector =
if (isFrontCamera) CameraSelector.DEFAULT_FRONT_CAMERA
else CameraSelector.DEFAULT_BACK_CAMERA
cameraProvider.unbindAll()
val camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture)
cameraControl = camera.cameraControl
cameraInfo = camera.cameraInfo
}
private fun setListeners() {
binding.btnCapture.setOnClickListener { takeCapture() }
binding.btnFlash.setOnClickListener { toggleFlashlight() }
binding.btnTransition.setOnClickListener { toggleCamera() }
}
private fun takeCapture() {
imageCapture?.let { capture ->
val imageFile = File(getExternalFilesDir(null), "captured_image.jpg")
val outputOptions = ImageCapture.OutputFileOptions.Builder(imageFile).build()
capture.takePicture(outputOptions, ContextCompat.getMainExecutor(this),
object : ImageCapture.OnImageSavedCallback {
override fun onError(exc: ImageCaptureException) {
Log.e("CameraX", "사진 촬영 실패: ${exc.message}", exc)
}
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
val savedUri = Uri.fromFile(imageFile)
val resultIntent = Intent().apply {
putExtra("imageUri", savedUri.toString())
}
setResult(RESULT_OK, resultIntent)
finish()
}
}
)
}
}
private fun toggleFlashlight() {
cameraControl.enableTorch(!isFlashOn)
isFlashOn = !isFlashOn
}
private fun toggleCamera() {
isFrontCamera = !isFrontCamera
bindCameraUseCases()
}
}
안드로이드 카메라 프리뷰 예제 다운로드
해당 예제는 cameraPreview 모듈을 생성하여 구현한 카메라 프리뷰 예제입니다.
아래 링크를 통해서 다운로드가 가능하고 직접 실행하여 확인이 가능합니다.
관련 글
'안드로이드 > 코틀린' 카테고리의 다른 글
안드로이드 UART 시리얼 통신 예제 다운로드 (0) | 2024.11.24 |
---|---|
안드로이드 블루투스 소켓 통신 예제 다운로드 (0) | 2024.11.23 |
안드로이드 USB 소켓 통신 (예제 다운로드) (0) | 2024.11.19 |
안드로이드 WiFi 소켓 통신 (예제 다운로드) (0) | 2024.11.16 |
안드로이드 화면 전환: Navigation 기능 사용법 및 예제 (2) | 2024.07.13 |
댓글