본문으로 건너뛰기

제11장: 캡처 유형

Camera2 파이프라인(10장)은 거대한 컨베이어 벨트와 같으며, CaptureRequest는 하드웨어가 각 프레임을 어떻게 처리해야 하는지 알려주는 작업 지침서입니다. 하지만 이 벨트에 지침서를 어떻게 올릴까요?

모든 프레임에 대해 capture()를 수동으로 호출해야 할까요? 아니면 한 번만 설정하면 알아서 돌아가게 할 수 있을까요? 고속 연사 촬영은 어떻게 처리할까요? 이 장에서는 요청을 제출하는 세 가지 방식과 안드로이드 프레임워크에서 제공하는 미리 구성된 "템플릿"에 대해 알아봅니다.

Android Camera Parameters 앱Capture 탭에서 이 세 가지 모드가 실제로 작동하는 모습을 확인할 수 있습니다. 앱은 각 모드에서 발생하는 프레임 속도와 메타데이터 변화를 실시간으로 보여줍니다.


1. 반복 요청 (Repeating Requests)

반복 요청은 카메라 미리보기의 심장박동입니다. 한 번 제출하면 명시적으로 중단하거나 다른 요청으로 교체할 때까지 카메라가 가능한 한 빨리(보통 30fps 또는 60fps) 동일한 지침으로 프레임을 계속 생성하도록 합니다.

  • 메서드: CameraCaptureSession.setRepeatingRequest()
  • 주요 용도: 라이브 미리보기 표시, 실시간 QR 코드 스캔, 비디오 녹화 중 프레임 스트리밍.
  • 작동 방식: 프레임 N이 완료되면 프레임워크가 자동으로 동일한 CaptureRequest를 대기열의 끝에 다시 넣습니다.
// 일반적인 미리보기 설정
val previewRequest = previewRequestBuilder.build()
captureSession.setRepeatingRequest(
previewRequest,
captureCallback, // 매 프레임마다 메타데이터를 받기 위한 콜백
backgroundHandler
)

중요: 반복 요청은 가장 낮은 우선순위를 갖습니다. 단일 요청이나 연사 요청이 들어오면 반복 요청은 일시적으로 "대기" 상태가 되고, 우선순위가 높은 요청들이 모두 처리된 후에 다시 재개됩니다.


2. 단일 요청 (One-shot / Single Captures)

단일 요청은 컨베이어 벨트에 단 하나의 지침서만 올리는 것입니다. 하드웨어는 그 지침에 따라 정확히 한 프레임을 처리하고 멈춥니다.

  • 메서드: CameraCaptureSession.capture()
  • 주요 용도: 고해상도 사진 촬영, AF(자동 초점) 트리거 실행, 수동 노출 설정 한 번 적용.
  • 작동 방식: 현재 진행 중인 반복 요청 바로 다음에 삽입됩니다.
// 고해상도 사진 한 장 촬영
val stillRequest = stillRequestBuilder.build()
captureSession.capture(
stillRequest,
object : CameraCaptureSession.CaptureCallback() {
override fun onCaptureCompleted(...) {
// 사진 촬영 완료!
}
},
backgroundHandler
)

팁: 단일 요청을 보낼 때 반복 요청을 멈출 필요가 없습니다. 시스템이 알아서 단일 요청을 먼저 처리하고 미리보기를 계속 이어갑니다.


3. 연사 요청 (Burst Requests)

연사 요청은 순서가 정해진 여러 장의 지침서를 묶어서 한꺼번에 제출하는 것입니다. 이 요청들은 중간에 다른 요청(반복 요청 포함)이 끼어들지 않고 반드시 연속적으로 처리됩니다.

  • 메서드: CameraCaptureSession.captureBurst()
  • 주요 용도: HDR 촬영(서로 다른 노출로 3~5장 촬영), 제로 셔터 랙(ZSL), 고속 연사 모드.
  • 작동 방식: 리스트에 담긴 모든 CaptureRequest가 원자적(atomic)으로 대기열에 추가됩니다.
// 노출값이 다른 3장의 사진을 연사로 촬영 (HDR용)
val burstRequests = listOf(requestEvMinus, requestEvZero, requestEvPlus)
captureSession.captureBurst(burstRequests, burstCallback, backgroundHandler)

주의: 연사 촬영 중에는 미리보기 프레임이 일시 정지될 수 있습니다(블랙아웃 현상). 하드웨어가 연사 요청을 처리하는 데 모든 자원을 집중하기 때문입니다.


요청 템플릿 (Capture Templates)

CaptureRequest에는 설정해야 할 파라미터가 수백 개나 됩니다. 이를 처음부터 하나씩 설정하는 것은 고통스러운 일입니다. 안드로이드는 일반적인 유스케이스에 맞춰 최적화된 파라미터 세트인 템플릿을 제공합니다.

cameraDevice.createCaptureRequest(Template_ID)를 호출하여 시작점을 선택할 수 있습니다.

템플릿 ID최적화 대상특징
TEMPLATE_PREVIEW화면 표시용부드러운 프레임 속도 우선, 전력 소모 절감, 중간 품질의 노이즈 감소.
TEMPLATE_STILL_CAPTURE고품질 사진최고 품질의 이미지 처리(노이즈 감소, 샤프닝) 우선, 프레임 속도는 느려질 수 있음.
TEMPLATE_RECORD비디오 녹화일정한 프레임 속도와 노출 유지, 비디오 흔들림 보정(EIS) 활성화 가능성 높음.
TEMPLATE_VIDEO_SNAPSHOT비디오 중 사진녹화 중 프레임 품질을 높이되, 비디오 스트림이 끊기지 않도록 속도 조절.
TEMPLATE_MANUAL수동 제어자동 기능(3A)이 대부분 꺼진 상태로 시작. 개발자가 모든 값을 직접 설정할 때 유용.
TEMPLATE_ZERO_SHUTTER_LAG무지연 촬영셔터를 누르는 순간의 프레임을 즉시 캡처하기 위해 백그라운드에서 항상 고해상도로 구동.

템플릿 사용 예시

// 사진 촬영용 요청 생성 시
val builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE)
// 이제 템플릿 설정 위에 필요한 값만 살짝 수정합니다.
builder.set(CaptureRequest.JPEG_QUALITY, 100)
val request = builder.build()

캡처 유형 선택 가이드

상황권장 유형권장 템플릿
카메라를 켜고 화면을 보여줄 때setRepeatingRequestTEMPLATE_PREVIEW
"찰칵" 버튼을 눌러 사진을 저장할 때captureTEMPLATE_STILL_CAPTURE
비디오 녹화 버튼을 눌렀을 때setRepeatingRequestTEMPLATE_RECORD
HDR을 위해 밝기가 다른 사진 3장을 찍을 때captureBurstTEMPLATE_STILL_CAPTURE
사용자가 초점을 맞추려고 화면을 터치했을 때capture (AF 트리거 전용)TEMPLATE_PREVIEW

요약

  1. 반복(Repeating): 멈추라고 할 때까지 계속 프레임을 생성합니다. (미리보기용)
  2. 단일(One-shot): 요청한 프레임을 딱 한 번 생성하고 끝냅니다. (사진 촬영용)
  3. 연사(Burst): 여러 프레임을 순서대로 묶어서 생성합니다. (HDR/고속 촬영용)
  4. 템플릿: 수백 개의 설정을 직접 할 필요 없이, 용도에 맞는 기본값 세트를 선택해서 시작할 수 있습니다.

다음 단계

이제 요청을 보내는 방법을 알았습니다. 하지만 캡처된 이미지는 어디로 갈까요? 제12장: ImageReader와 데이터 처리에서는 하드웨어에서 생성된 픽셀 데이터를 앱에서 받아보고 파일로 저장하는 실제적인 방법을 배웁니다.