Skip to content

영수증 스캔 시 초점이 잡히지 않는 문제

Safari edited this page Dec 12, 2024 · 6 revisions

문제 상황

카메라를 통해 영수증을 촬용할 때 디바이스에 따라 초점이 잡히지 않는 문제 발생

아이폰 11 Pro 아이폰 16 Pro

위와 같이 11 Pro 모델에서는 정상적으로 촬영이 가능한 반면, 16 Pro 모델에서는 초점이 잡히지 않아 영수증 스캔이 불가능한 상황

해결 방법

기존 코드

  func setupCamera() throws {
    // 사용 가능한 카메라 중 후면 카메라를 선택
    guard let backCamera = AVCaptureDevice.default(for: .video),
          let input = try? AVCaptureDeviceInput(device: backCamera) else {
      throw MoneyMongError.appError(.cameraAccess, errorMessage: "설정에서 카메라 접근을 허용해주세요!")
    }
    
    // ..중략
  }

1차 해결 방법

초점이 잡히지 않는 문제를 해결하기 위해 카메라의 초점을 자동으로 조절할 수 있도록 configureCameraFocus 메서드 구현

  func setupCamera() throws {
    // 사용 가능한 카메라 중 후면 카메라를 선택
    guard let backCamera = AVCaptureDevice.default(for: .video),
          let input = try? AVCaptureDeviceInput(device: backCamera) else {
      throw MoneyMongError.appError(.cameraAccess, errorMessage: "설정에서 카메라 접근을 허용해주세요!")
    }
    
    configureCameraFocus(backCamera)

    // ..중략
  }

  private func configureCameraFocus(_ camera: AVCaptureDevice) throws {
    try camera.lockForConfiguration()
    
    // 연속 자동 초점 모드 설정
    if camera.isFocusModeSupported(.continuousAutoFocus) {
      camera.focusMode = .continuousAutoFocus
    }
    
    // 연속 자동 노출 모드 설정
    if camera.isExposureModeSupported(.continuousAutoExposure) {
      camera.exposureMode = .continuousAutoExposure
    }
    
    camera.unlockForConfiguration()
  }

자동 초점 모드를 설정했음에도 초점이 잡히지 않는 문제가 해결되지 않았다.

2차 해결 방법

11 Pro와 16 Pro는 동일하게 광각, 초광각, 망원 3개의 카메라를 가지고있지만, 테스트해본 결과 사용되는 카메라의 차이가 있다는 것을 확인할 수 있었다.

또한, 일반 모델의 경우 Pro 모델과 카메라 구성의 차이가 있기 때문에 디바이스에 따라 처리해줄 필요가 있다고 판단했다.

먼저,

    let deviceTypes: [AVCaptureDevice.DeviceType] = [
      .builtInTripleCamera,  // 트리플 카메라 (프로 모델)
      .builtInDualCamera,    // 듀얼 카메라 (일반 모델)
      .builtInWideAngleCamera // 광각 카메라 (단일 렌즈 카메라)
    ]

배열을 통해 디바이스 타입을 정의한다. 배열의 순서는 DiscoverySession 통해 검색 시 우선순위에 영향이 있으므로 3개 -> 2개 -> 1개 순서로 나열하였다.

    guard let backCamera = AVCaptureDevice.DiscoverySession(
      deviceTypes: deviceTypes,
      mediaType: .video,
      position: .back
    ).devices.first,
          let input = try? AVCaptureDeviceInput(device: backCamera) else {
      throw MoneyMongError.appError(.cameraAccess, errorMessage: "설정에서 카메라 접근을 허용해주세요!")
    }

DiscoverySession을 통해 카메라 장치를 검색하고, 결과의 첫번째 요소를 가져와 사용하면 사용자 디바이스에 따라 가장 적합한 카메라 장치를 사용할 수 있었다.

참고