Swift 4 拍摄照片,照片输出 returns 无
Swift 4 Capture Photo, photoOutput returns nil
目前我有两个不同的视图控制器和一个在它们之间切换的按钮。
我希望能够在每个设备上拍摄设备输入的照片。
我目前可以拍摄后置摄像头的照片进行处理,效果很好,但是当我尝试在另一个控制器中为第二个视图编写相同的代码时,照片输出 returns没有,但是当我登录每个设备时,它仍然显示前后摄像头。
我是 swift 的新手,不确定为什么会这样。
ViewController class, viewDidLoad 和变量:
class AddUserController: UIViewController , AVCaptureVideoDataOutputSampleBufferDelegate , UITextFieldDelegate{
//variable for captureing video feed
var captureSessionFront = AVCaptureSession()
//variable for rendering camera to the view
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
var frontCamera: AVCaptureDevice?
var backCamera: AVCaptureDevice?
var currentCamera2: AVCaptureDevice?
var PhotoOutputFront: AVCapturePhotoOutput?
var cameraPreviewLayer2: AVCaptureVideoPreviewLayer?
var tempImage: UIImage?
var tempstring: String?
private var maskLayer = [CAShapeLayer]()
@IBOutlet weak var textField: UITextField!
//button action to save the user to the collection
@IBAction func saveFaceBtn(_ sender: Any) {
let settings = AVCapturePhotoSettings()
PhotoOutputFront?.capturePhoto(with: settings, delegate: self)
//print(PhotoOutputFront!)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//hide keyboard
self.textField.delegate = self
//video capture functions
setupCaptureSession()
setupDevice()
setupInputOutput()
setupPreview()
startRunningCaptureSession()
函数:
func setupCaptureSession() {
captureSessionFront.sessionPreset = AVCaptureSession.Preset.photo
}
func setupDevice() {
//discover devices
let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(
deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera],
mediaType: AVMediaType.video,
position: AVCaptureDevice.Position.unspecified)
//find devices and check if frint or back cameras discovered
let devices = deviceDiscoverySession.devices
for device in devices{
print(device)
if device.position == AVCaptureDevice.Position.front{
frontCamera = device
} else if device.position == AVCaptureDevice.Position.back{
backCamera = device
}
}
currentCamera2 = frontCamera
}
func setupInputOutput() {
do
{
let captureDeviceInput2 = try AVCaptureDeviceInput(device: currentCamera2!)
captureSessionFront.addInput(captureDeviceInput2)
PhotoOutputFront?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
print(PhotoOutputFront)
}
catch
{
print(error)
}
}
func setupPreview() {
cameraPreviewLayer2 = AVCaptureVideoPreviewLayer(session: captureSessionFront)
cameraPreviewLayer2?.videoGravity = AVLayerVideoGravity.resizeAspectFill
cameraPreviewLayer2?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
cameraPreviewLayer2?.frame = self.view.frame
self.view.layer.insertSublayer(cameraPreviewLayer2!, at: 0)
}
func startRunningCaptureSession() {
captureSessionFront.startRunning()
}
保存拍摄照片的扩展程序:
extension AddUserController: AVCapturePhotoCaptureDelegate {
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
print("before if let")
if let imageData = photo.fileDataRepresentation(){
tempImage = UIImage(data: imageData)
print(tempImage!)
//check to see if name is empty
let tempstring = self.textField.text
if(tempstring != nil || tempstring != ""){
print(tempstring!)
//addPhotoToCollection()
}
}
}
}
它一定是设置了输入输出,但我不确定我哪里出错了,因为这段代码适用于我的主 viewcontroller 中的后置摄像头。我认为它与此功能有关,因为在我的其他控制器中 "PhotoOutput" 不 return nil。在这里,"PhotoOutputFront" returns nil.
view func setupInputOutput() {
do
{
let captureDeviceInput2 = try AVCaptureDeviceInput(device: currentCamera2!)
captureSessionFront.addInput(captureDeviceInput2)
PhotoOutputFront?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
print(PhotoOutputFront)
}
catch
{
print(error)
}
}
如有任何帮助,我们将不胜感激。提前致谢!
问题是我没有将捕获设备添加为捕获会话的输入,也没有添加捕获会话的输出。
希望这对其他在使用 avcapture 设备时遇到问题的人有所帮助。 :)
func setupInputOutput() {
do
{
let captureDeviceInput2 = try AVCaptureDeviceInput(device: currentCamera2!)
captureSessionFront.addInput(captureDeviceInput2)
PhotoOutputFront = AVCapturePhotoOutput()
PhotoOutputFront?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
captureSessionFront.addOutput(PhotoOutputFront!)
}
catch
{
print(error)
}
}
添加输出:
if captureSessionFront?.canAddOutput(PhotoOutputFront) {
let settings = AVCapturePhotoSettings()
let previewPixelType =
settings.__availablePreviewPhotoPixelFormatTypes.first!
let previewFormat = [kCVPixelBufferPixelFormatTypeKey as String: previewPixelType,
kCVPixelBufferWidthKey as String: 160,
kCVPixelBufferHeightKey as String: 160]
settings.previewPhotoFormat = previewFormat
settings.isHighResolutionPhotoEnabled =
PhotoOutputFront.isHighResolutionCaptureEnabled
PhotoOutputFront.setPreparedPhotoSettingsArray([settings], completionHandler: { (finished, anError) in
guard let error = anError else { return }
debugPrint("Failed to set photo settings with: \(error.localizedDescription)")
})
captureSessionFront.addOutput(PhotoOutputFront)
}
在添加输出之前,添加输入:
if captureSessionFront.canAddInput(captureDeviceInput2) {
captureSessionFront.addInput(captureDeviceInput2)
}
目前我有两个不同的视图控制器和一个在它们之间切换的按钮。 我希望能够在每个设备上拍摄设备输入的照片。
我目前可以拍摄后置摄像头的照片进行处理,效果很好,但是当我尝试在另一个控制器中为第二个视图编写相同的代码时,照片输出 returns没有,但是当我登录每个设备时,它仍然显示前后摄像头。
我是 swift 的新手,不确定为什么会这样。
ViewController class, viewDidLoad 和变量:
class AddUserController: UIViewController , AVCaptureVideoDataOutputSampleBufferDelegate , UITextFieldDelegate{
//variable for captureing video feed
var captureSessionFront = AVCaptureSession()
//variable for rendering camera to the view
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
var frontCamera: AVCaptureDevice?
var backCamera: AVCaptureDevice?
var currentCamera2: AVCaptureDevice?
var PhotoOutputFront: AVCapturePhotoOutput?
var cameraPreviewLayer2: AVCaptureVideoPreviewLayer?
var tempImage: UIImage?
var tempstring: String?
private var maskLayer = [CAShapeLayer]()
@IBOutlet weak var textField: UITextField!
//button action to save the user to the collection
@IBAction func saveFaceBtn(_ sender: Any) {
let settings = AVCapturePhotoSettings()
PhotoOutputFront?.capturePhoto(with: settings, delegate: self)
//print(PhotoOutputFront!)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//hide keyboard
self.textField.delegate = self
//video capture functions
setupCaptureSession()
setupDevice()
setupInputOutput()
setupPreview()
startRunningCaptureSession()
函数:
func setupCaptureSession() {
captureSessionFront.sessionPreset = AVCaptureSession.Preset.photo
}
func setupDevice() {
//discover devices
let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(
deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera],
mediaType: AVMediaType.video,
position: AVCaptureDevice.Position.unspecified)
//find devices and check if frint or back cameras discovered
let devices = deviceDiscoverySession.devices
for device in devices{
print(device)
if device.position == AVCaptureDevice.Position.front{
frontCamera = device
} else if device.position == AVCaptureDevice.Position.back{
backCamera = device
}
}
currentCamera2 = frontCamera
}
func setupInputOutput() {
do
{
let captureDeviceInput2 = try AVCaptureDeviceInput(device: currentCamera2!)
captureSessionFront.addInput(captureDeviceInput2)
PhotoOutputFront?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
print(PhotoOutputFront)
}
catch
{
print(error)
}
}
func setupPreview() {
cameraPreviewLayer2 = AVCaptureVideoPreviewLayer(session: captureSessionFront)
cameraPreviewLayer2?.videoGravity = AVLayerVideoGravity.resizeAspectFill
cameraPreviewLayer2?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
cameraPreviewLayer2?.frame = self.view.frame
self.view.layer.insertSublayer(cameraPreviewLayer2!, at: 0)
}
func startRunningCaptureSession() {
captureSessionFront.startRunning()
}
保存拍摄照片的扩展程序:
extension AddUserController: AVCapturePhotoCaptureDelegate {
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
print("before if let")
if let imageData = photo.fileDataRepresentation(){
tempImage = UIImage(data: imageData)
print(tempImage!)
//check to see if name is empty
let tempstring = self.textField.text
if(tempstring != nil || tempstring != ""){
print(tempstring!)
//addPhotoToCollection()
}
}
}
}
它一定是设置了输入输出,但我不确定我哪里出错了,因为这段代码适用于我的主 viewcontroller 中的后置摄像头。我认为它与此功能有关,因为在我的其他控制器中 "PhotoOutput" 不 return nil。在这里,"PhotoOutputFront" returns nil.
view func setupInputOutput() {
do
{
let captureDeviceInput2 = try AVCaptureDeviceInput(device: currentCamera2!)
captureSessionFront.addInput(captureDeviceInput2)
PhotoOutputFront?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
print(PhotoOutputFront)
}
catch
{
print(error)
}
}
如有任何帮助,我们将不胜感激。提前致谢!
问题是我没有将捕获设备添加为捕获会话的输入,也没有添加捕获会话的输出。
希望这对其他在使用 avcapture 设备时遇到问题的人有所帮助。 :)
func setupInputOutput() {
do
{
let captureDeviceInput2 = try AVCaptureDeviceInput(device: currentCamera2!)
captureSessionFront.addInput(captureDeviceInput2)
PhotoOutputFront = AVCapturePhotoOutput()
PhotoOutputFront?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
captureSessionFront.addOutput(PhotoOutputFront!)
}
catch
{
print(error)
}
}
添加输出:
if captureSessionFront?.canAddOutput(PhotoOutputFront) {
let settings = AVCapturePhotoSettings()
let previewPixelType =
settings.__availablePreviewPhotoPixelFormatTypes.first!
let previewFormat = [kCVPixelBufferPixelFormatTypeKey as String: previewPixelType,
kCVPixelBufferWidthKey as String: 160,
kCVPixelBufferHeightKey as String: 160]
settings.previewPhotoFormat = previewFormat
settings.isHighResolutionPhotoEnabled =
PhotoOutputFront.isHighResolutionCaptureEnabled
PhotoOutputFront.setPreparedPhotoSettingsArray([settings], completionHandler: { (finished, anError) in
guard let error = anError else { return }
debugPrint("Failed to set photo settings with: \(error.localizedDescription)")
})
captureSessionFront.addOutput(PhotoOutputFront)
}
在添加输出之前,添加输入:
if captureSessionFront.canAddInput(captureDeviceInput2) {
captureSessionFront.addInput(captureDeviceInput2)
}