我正在运行ios 12 swift 4.2。
我已经实现了一个基本的相机捕获会话,并且正在从中单击图像。一切都很好,直到我在自动/打开/关闭模式之间切换闪光灯为止。单击第一张照片然后更改闪光模式后,该应用程序崩溃并显示错误:
@media only screen and (min-width: 800px) and (max-width: 825px) and (max-height: 500px) {...}
以下是摄像机的实现:
[AVCapturePhotoOutput capturePhotoWithSettings:delegate:] Settings may not be re-used'
我真的不了解如何精确地重用var captureSession: AVCaptureSession!
var videoPreviewLayer: AVCaptureVideoPreviewLayer!
var capturePhotoOutput: AVCapturePhotoOutput!
let capturePhotoSettings = AVCapturePhotoSettings()
var previewView: UIView!
override func viewDidLoad() {
startCameraSession()
setupCaptureOutput()
}
@objc // Tap on a button to capture
func takePhotoOnTap() {
guard let capturePhotoOutput = self.capturePhotoOutput else { return }
capturePhotoSettings.isAutoStillImageStabilizationEnabled = true
capturePhotoSettings.isHighResolutionPhotoEnabled = true
capturePhotoSettings.flashMode = .auto
let _ = getSettings(camera: captureDevice!, flashMode: spotmiCameraOptions.flashMode)
capturePhotoOutput.capturePhoto(with: capturePhotoSettings, delegate: self)
}
//This is a delegate method from the button
func toggleFlash(mode: FlashMode) {
switch mode {
case .auto:
capturePhotoSettings.flashMode = .auto
case .enabled:
capturePhotoSettings.flashMode = .on
case .disabled:
capturePhotoSettings.flashMode = .off
}
}
func setupCaptureOutput() {
capturePhotoOutput = AVCapturePhotoOutput()
capturePhotoOutput.isHighResolutionCaptureEnabled = true
captureSession.addOutput(capturePhotoOutput)
}
func startCameraSession() {
let captureDevice = AVCaptureDevice.default(.builtInDualCamera, for: AVMediaType.video, position: .back)
do {
let input = try AVCaptureDeviceInput(device: captureDevice!)
captureSession = AVCaptureSession()
captureSession.addInput(input)
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
videoPreviewLayer.videoGravity = .resizeAspectFill
videoPreviewLayer.frame = self.view.layer.bounds
camcontainer.layer.addSublayer(videoPreviewLayer)
captureSession.startRunning()
} catch {
print(error.localizedDescription)
}
}
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?, previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {
guard error == nil, let sampleBuffer = photoSampleBuffer else {
print("error capturing photo due to \(String(describing: error?.localizedDescription))")
return
}
guard let imageData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: sampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer) else { return }
let capturedImage = UIImage(data: imageData, scale: 1.0)
if let image = capturedImage {
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}
}
func getSettings(camera: AVCaptureDevice, flashMode: FlashMode) -> AVCapturePhotoSettings {
let settings = capturePhotoSettings
if camera.hasFlash {
switch flashMode {
// case .auto: settings.flashMode = .auto
case .enabled: settings.flashMode = .on
case .disabled: settings.flashMode = .off
default: settings.flashMode = .auto
}
}
return settings
}
并每次使用不同的闪光模式进行更改。我遇到了几个问题,但主要是关于手电筒的问题。我正在寻找闪光灯。
非常感谢您的帮助。
答案 0 :(得分:2)
AVCapturePhotoSettings
对象是唯一的,并且无法重复使用,因此,每次使用此方法都需要获取新设置:
func getSettings(camera: AVCaptureDevice, flashMode: CurrentFlashMode) -> AVCapturePhotoSettings {
let settings = AVCapturePhotoSettings()
if camera.hasFlash {
switch flashMode {
case .auto: settings.flashMode = .auto
case .on: settings.flashMode = .on
default: settings.flashMode = .off
}
}
return settings
}
如您所见,不需要lockConfiguration
。
CurrentFlashMode
是enum
,其创建目的是为了使内容保持清楚:
枚举CurrentFlashMode { 情况下 案子 案例自动 }
然后只需在拍摄照片时使用它即可
@IBAction func captureButtonPressed(_ sender: UIButton) {
let currentSettings = getSettings(camera: currentCamera, flashMode: currentFlashMode)
photoOutput.capturePhoto(with: currentSettings, delegate: self)
}
答案 1 :(得分:0)
AVCapturePhotoSettings
中的引号,请参阅最后一个重要部分:
摘要
用于单个照片捕获请求的功能和设置的规范。
声明
AVCapturePhotoSettings类:NSObject 讨论
要拍摄照片,请创建并配置一个AVCapturePhotoSettings对象,然后将其传递给AVCapturePhotoOutput capturePhoto(with:delegate :)方法。 AVCapturePhotoSettings实例可以包括设置的任何组合,无论该组合对于给定的捕获会话是否有效。通过将照片设置对象传递给AVCapturePhotoOutputcapturePhoto(with:delegate :)方法来启动捕获时,照片捕获输出会验证您的设置以确保确定性的行为。例如,flashMode设置必须指定一个在照片输出的受支持的FlashModes数组中存在的值。有关详细的验证规则,请参见下面的每个属性描述。
重要
将AVCapturePhotoSettings实例重用于多个捕获是非法的。如果设置对象的uniqueID值与任何以前使用的设置对象的uniqueID值匹配,则调用capturePhoto(with:delegate :)方法将引发异常(invalidArgumentException)。
To reuse a specific combination of settings, use the init(from:)
初始化程序可从现有照片设置对象创建新的唯一AVCapturePhotoSettings实例。
与您同样的问题:this github issue