当前位置: 首页 > 面试题库 >

无法使用AVCapturePhotoOutput捕获照片swift + Xcode

许振海
2023-03-14
问题内容

我正在使用自定义相机应用程序,本教程使用的是iOS 10弃用的AVCaptureStillImageOutput。我已经设置了相机,现在只能使用如何拍照了。

这是我有相机的全景

import UIKit
import AVFoundation

var cameraPos = "back"

class View3: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate {


@IBOutlet weak var clickButton: UIButton!
@IBOutlet var cameraView: UIView!
var session: AVCaptureSession?
var stillImageOutput: AVCapturePhotoOutput?
var videoPreviewLayer: AVCaptureVideoPreviewLayer?

override func viewDidLoad() {
    super.viewDidLoad()        
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    clickButton.center.x = cameraView.bounds.width/2
    loadCamera()
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
 }

@IBAction func clickCapture(_ sender: UIButton) {

    if let videoConnection = stillImageOutput!.connection(withMediaType: AVMediaTypeVideo) {
       // This is where I need help 
        }
}

@IBAction func changeDevice(_ sender: UIButton) {
    if cameraPos == "back"
    {cameraPos = "front"}

    else
    {cameraPos = "back"}


    loadCamera()
}

func loadCamera()
{
    session?.stopRunning()
    videoPreviewLayer?.removeFromSuperlayer()

    session = AVCaptureSession()
    session!.sessionPreset = AVCaptureSessionPresetPhoto

    var backCamera = AVCaptureDevice.defaultDevice(withDeviceType: .builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: .front)

    if cameraPos == "back"
    {
        backCamera = AVCaptureDevice.defaultDevice(withDeviceType: .builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: .back)
    }

    var error: NSError?
    var input: AVCaptureDeviceInput!
    do {
        input = try AVCaptureDeviceInput(device: backCamera)
    } catch let error1 as NSError {
        error = error1
        input = nil
        print(error!.localizedDescription)
    }

    if error == nil && session!.canAddInput(input) {
        session!.addInput(input)

        stillImageOutput = AVCapturePhotoOutput()

if session!.canAddOutput(stillImageOutput) {
            session!.addOutput(stillImageOutput)
            videoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
            videoPreviewLayer?.frame = cameraView.bounds
            videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
            videoPreviewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait

            cameraView.layer.addSublayer(videoPreviewLayer!)
            session!.startRunning()

        }        }
}
}

这是我需要帮助的地方

@IBAction func clickCapture(_ sender: UIButton) {

if let videoConnection = stillImageOutput!.connection(withMediaType: AVMediaTypeVideo) {
   // This is where I need help 
    }
}

我已经在这里回答了如何使用AVCapturePhotoOutput,但是我不明白如何在该代码中合并该代码,因为它涉及到声明一个新类。


问题答案:

你快到了。

查看AVCapturePhotoOutput
文档以获取更多帮助。

这些是拍摄照片的步骤。

  1. 创建一个AVCapturePhotoOutput对象。使用其属性来确定支持的捕获设置并启用某些功能(例如,是否捕获实时照片)。
  2. 创建并配置AVCapturePhotoSettings对象以选择特定捕获的功能和设置(例如,启用图像稳定还是闪光灯)。
  3. 通过将照片设置对象capturePhoto(with:delegate:)与实现AVCapturePhotoCaptureDelegate协议的委托对象一起传递给方法来捕获图像 。然后,照片捕获输出将呼叫您的代表,以在捕获过程中将重大事件通知您。

在您的clickCapture方法上具有以下代码,并且不要忘记在类中进行确认和实现委托。

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
self.cameraOutput.capturePhoto(with: settings, delegate: self)

输出为 AVCaptureStillImageOutput

如果您打算通过视频连接拍摄照片。您可以按照以下步骤操作。

步骤1:建立连线

if let videoConnection = stillImageOutput!.connectionWithMediaType(AVMediaTypeVideo) {
  // ...
  // Code for photo capture goes here...
}

步骤2:拍摄相片

  • captureStillImageAsynchronouslyFromConnection上调用该函数stillImageOutput
  • sampleBuffer表示被捕捉的数据。
stillImageOutput?.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler: { (sampleBuffer, error) -> Void in
  // ...
  // Process the image data (sampleBuffer) here to get an image file we can put in our captureImageView
})

步骤3:处理图像数据

  • 我们将需要采取一些步骤来处理在sampleBuffer中找到的图像数据,以便最终获得一个UIImage,我们可以将其插入到captureImageView中并在应用程序的其他位置轻松使用。
if sampleBuffer != nil {
  let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
  let dataProvider = CGDataProviderCreateWithCFData(imageData)
  let cgImageRef = CGImageCreateWithJPEGDataProvider(dataProvider, nil, true, CGColorRenderingIntent.RenderingIntentDefault)
  let image = UIImage(CGImage: cgImageRef!, scale: 1.0, orientation: UIImageOrientation.Right)
  // ...
  // Add the image to captureImageView here...
}

步骤4:储存图片

根据您的需要将图像保存到照片库或在图像视图中显示

有关更多详细信息,请查看 “ 捕捉照片” 下的“
创建自定义相机视图指南 ”。 __



 类似资料:
  • 在我的应用程序中,当我通过以下方式调用相机意图时: 它不调用方法。 我的应用程序中的问题是,有时它调用这个方法,但在捕获照片后的一段时间,它再次来到照片捕获屏幕。

  • 我们正在整合微软Azure广告与我们的应用程序。我正在尝试使用微软图形API(https://graph.microsoft.com/v1.0/users/{id | userPrincipalName }/photo/$ value)获取用户个人资料图片。但这对我不起作用。我已经在应用程序中给出了该API所需的所有权限,但每次都得不到响应。你能告诉我我错过了什么配置吗? 答复: 谢谢

  • 问题内容: 我想将预览层“流式传输”到我的服务器,但是,我只希望发送特定的帧。基本上,我想拍摄AVCaptureVideoPreviewLayer的快照,将其缩放到28 * 28,将其转换为强度数组,然后将其发送到我的python后端处理其余部分的套接字层。 这里的问题是AVCapturePhotoOutput的捕获功能异常缓慢。我不能重复调用该函数。更不用说它总是使相机的快门声哈哈。 另一个问题

  • 问题内容: 我想从我的应用程序中的用户照片库访问照片,而我正在查看UIImagePickerController。但是,我想知道是否可以在不将照片实际存储在应用程序中的情况下访问和查看照片库中的照片?因此,基本上,该应用将存储对所选照片的​​引用,而不是存储照片本身。这是为了防止该应用占用大量空间来存储每张照片。 谢谢! 问题答案: 它不是那么简单,但是正如Rob所提到的,您可以保存照片资产url

  • 问题内容: 我一直在使用自定义相机,最近我与Swift 3一起升级到了Xcode 8 beta。 但是,我现在收到警告: iOS 10.0中不推荐使用“ AVCaptureStillImageOutput”:改用AVCapturePhotoOutput 由于这是相当新的内容,因此我没有看到太多信息。这是我当前的代码: 我尝试查看,但是我不确定如何使用它。有人知道如何使用吗?谢谢。 问题答案: 更新

  • 问题内容: 我需要在活动中获得并显示照片库中最近拍摄的3张照片,而无需任何点击。 完成此步骤后,滚动时,我应该以3 x 3的方式拍摄其他照片。 您知道快速执行此操作的正确方法吗?谢谢。 问题答案: 这是使用适用于iOS 8+设备的框架的解决方案: