-
Android에서 Camera2 API를 활용한 RAW 이미지 캡처영상처리 2025. 2. 24. 16:20728x90
일반적인 스마트폰 카메라는 JPG 형식의 이미지만 저장하지만, 보다 높은 화질과 후처리 가능성을 위해 RAW 이미지를 캡처하는 방법이 필요합니다. Camera2 API를 활용하면 스마트폰의 센서 데이터를 직접 RAW 포맷으로 저장할 수 있습니다. 이 글에서는 RAW 이미지 캡처 앱을 개발하는 방법을 설명합니다.
1. RAW 이미지 캡처의 원리
RAW 데이터란?
RAW 데이터는 이미지 센서에서 수집된 원본 픽셀 정보를 그대로 저장하는 파일 형식입니다. 일반적으로 DNG(Digital Negative), ARW, CR2, NEF 등의 확장자로 저장됩니다. JPG와 달리, 압축 과정이 없어 세부 정보를 보존하며, 후처리를 통해 화이트 밸런스, 노출, 색감을 자유롭게 조정할 수 있습니다.
Android에서 RAW 캡처 지원 여부 확인
Android에서는 Camera2 API를 사용해야 RAW 캡처가 가능합니다. 하지만 모든 기기가 이를 지원하는 것은 아니므로, CameraCharacteristics를 이용해 RAW 지원 여부를 확인해야 합니다.
val manager = getSystemService(CAMERA_SERVICE) as CameraManager val cameraId = manager.cameraIdList[0] val characteristics = manager.getCameraCharacteristics(cameraId) val rawCapability = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)?.contains( CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_RAW ) ?: false if (!rawCapability) { Log.e("Camera2", "이 기기는 RAW 촬영을 지원하지 않습니다.") }
2. Camera2 API를 이용한 RAW 캡처 앱 개발
1. 프로젝트 설정
필요한 권한 추가
AndroidManifest.xml에 카메라 및 저장소 접근 권한을 추가합니다.
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
기본 레이아웃 구성
activity_main.xml 파일에서 TextureView와 버튼을 배치하여 촬영 기능을 구현합니다.
<TextureView android:id="@+id/textureView" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/captureButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="RAW 촬영" />
2. RAW 촬영 코드 구현
Camera2 API를 이용해 RAW 이미지를 촬영하고 저장하는 방법을 구현합니다.
카메라 초기화 및 세션 설정
Camera2 API를 사용하기 위해 카메라를 열고 세션을 생성합니다.
private fun openCamera() { val manager = getSystemService(CAMERA_SERVICE) as CameraManager val cameraId = manager.cameraIdList[0] val characteristics = manager.getCameraCharacteristics(cameraId) if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), 1) return } manager.openCamera(cameraId, object : CameraDevice.StateCallback() { override fun onOpened(camera: CameraDevice) { cameraDevice = camera setupImageReader() createCameraCaptureSession() } override fun onDisconnected(camera: CameraDevice) { camera.close() } override fun onError(camera: CameraDevice, error: Int) { camera.close() } }, backgroundHandler) }
RAW 데이터를 처리하기 위한 ImageReader 설정
private fun setupImageReader() { val pixelArraySize = cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE) val width = pixelArraySize?.width ?: 4000 val height = pixelArraySize?.height ?: 3000 imageReader = ImageReader.newInstance(width, height, ImageFormat.RAW_SENSOR, 2) imageReader.setOnImageAvailableListener({ reader -> val image = reader.acquireLatestImage() image?.let { saveRawImage(it) it.close() } }, backgroundHandler) }
RAW 이미지를 저장하는 코드
private fun saveRawImage(image: Image) { val fileName = "raw_image_${System.currentTimeMillis()}.dng" val outputStream: OutputStream? = applicationContext.contentResolver.openOutputStream( MediaStore.Images.Media.EXTERNAL_CONTENT_URI ) outputStream?.use { output -> val dngCreator = DngCreator(cameraCharacteristics, captureResult!!) dngCreator.writeImage(output, image) } }
3. RAW 촬영 실행
버튼을 눌러 RAW 촬영을 실행합니다.
captureButton.setOnClickListener { captureRawImage() }
private fun captureRawImage() { val captureBuilder = cameraDevice!!.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE).apply { addTarget(imageReader.surface) set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON) } captureSession!!.capture(captureBuilder.build(), object : CameraCaptureSession.CaptureCallback() { override fun onCaptureCompleted(session: CameraCaptureSession, request: CaptureRequest, result: TotalCaptureResult) { Log.d("Camera2", "📸 RAW 촬영 완료") } }, backgroundHandler) }
3. RAW 촬영 결과 예시
아래 이미지는 Camera2 API를 사용하여 RAW 포맷으로 촬영한 후 변환한 샘플입니다.
raw image capture app으로 촬영된 영상 변환 결과. color filter array의 pattern이 보인다. 4. 프로젝트 전체 코드
전체 프로젝트 코드는 GitHub에서 확인할 수 있습니다.
🔗https://github.com/Namseop2/RawCaptureProject
GitHub - Namseop2/RawCaptureProject: App for Raw image capture
App for Raw image capture. Contribute to Namseop2/RawCaptureProject development by creating an account on GitHub.
github.com
촬영된 DNG 파일을 png로 변환하는 코드는 아래에서 확인할 수 있습니다.
https://github.com/Namseop2/rawfile_converter
GitHub - Namseop2/rawfile_converter: RawFile(DNG) to PNG converter
RawFile(DNG) to PNG converter. Contribute to Namseop2/rawfile_converter development by creating an account on GitHub.
github.com
5. 결론
Camera2 API를 이용해 Android에서 RAW 이미지를 촬영하는 방법을 설명했습니다. RAW 데이터는 후처리를 통해 더욱 풍부한 색상과 디테일을 살릴 수 있으며, 촬영 후 DNG 파일을 Python과 OpenCV를 이용해 처리하면 더 유연한 활용이 가능합니다.
728x90'영상처리' 카테고리의 다른 글
opencv의 interpolation option, INTER_LINEAR / INTER_AREA 차이 (2) 2024.02.26