I’m having troubles taking RAW pictures with a zoomFactor
different than 1.0
.
In fact if I take a picture with the minimum zoom level everything works fine. However, if I try to zoom closer to a subject changing the zoomFactor
the app crashes with the following error:
Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** -[AVCapturePhotoOutput capturePhotoWithSettings:delegate:] When specifying Bayer raw capture, the videoZoomFactor of the video device must be set to 1.0’
This only happens when shooting RAW. If I shoot using the standard HEVC format everything works. I’m using Swift 4.2 and the AVFoundation Framework
Here’s the code referenced by the error:
extension CameraController: AVCapturePhotoCaptureDelegate, AVCaptureVideoDataOutputSampleBufferDelegate {
public func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
guard error == nil else {
print("Error capturing photo: (error!)")
return
}
// Access the file data representation of this photo.
guard let photoData = photo.fileDataRepresentation() else {
print("No photo data to write.")
return
}
print("Generating IMAGE with metadata n", photo.metadata)
if photo.isRawPhoto {
// Generate a unique URL to write the RAW file.
rawFileURL = makeUniqueDNGFileURL()
do {
// Write the RAW (DNG) file data to a URL.
try photoData.write(to: rawFileURL!)
print("RAW-URL Generated")
createRAWImageOnAlbum(withRAWURL: rawFileURL!)
} catch {
fatalError("Couldn't write DNG file to the URL.")
}
} else {
createHEVCPhotoOnAlbum(photo: photo)
}
}
private func makeUniqueDNGFileURL() -> URL {
let tempDir = FileManager.default.temporaryDirectory
let fileName = ProcessInfo.processInfo.globallyUniqueString
return tempDir.appendingPathComponent(fileName).appendingPathExtension("dng")
}
}
Do you know the reason of this?
I’m setting the zoomFactor
here:
func updateZoom(toValue: CGFloat) throws {
let session = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .unspecified)
guard let cameras = (session.devices.compactMap { $0 }) as? [AVCaptureDevice], !cameras.isEmpty else { throw CameraControllerError.noCamerasAvailable }
for camera in cameras {
if camera.position == .back {
self.rearCamera = camera
try camera.lockForConfiguration()
camera.ramp(toVideoZoomFactor: toValue, withRate: 4)
camera.unlockForConfiguration()
} else if camera.position == .front {
self.frontCamera = camera
try camera.lockForConfiguration()
camera.ramp(toVideoZoomFactor: toValue, withRate: 4)
camera.unlockForConfiguration()
}
}
}