使用自定义相机iOS 11.0 Swift拍照4.更新错误

时间:2017-09-28 21:03:04

标签: swift xcode camera swift4 xcode9

我的应用程序中有自定义相机并且工作正常,但在新更新后我收到此错误:

  

' jpegPhotoDataRepresentation(forJPEGSampleBuffer:previewPhotoSampleBuffer:)'在iOS 11.0中已弃用:请改用[AVCapturePhoto fileDataRepresentation]。

这是我收到错误的行:

    guard let imageData =
        AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer) else {
            return
    }

这是我的全部功能(如果需要):

//Take pic function
func photoOutput(_ captureOutput: AVCapturePhotoOutput,
                 didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?,
                 previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?,
                 resolvedSettings: AVCaptureResolvedPhotoSettings,
                 bracketSettings: AVCaptureBracketedStillImageSettings?,
                 error: Error?) {


    // Make sure we get some photo sample buffer
    guard error == nil,
        let photoSampleBuffer = photoSampleBuffer else {
            print("Error capturing photo: \(String(describing: error))")
            return
    }
    // Convert photo same buffer to a jpeg image data by using // AVCapturePhotoOutput
    guard let imageData =
        AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer) else {
            return
    }

    let dataProvider = CGDataProvider(data: imageData as CFData)

    let cgImageRef = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.absoluteColorimetric)


    let image = UIImage(cgImage: cgImageRef!, scale: 1.0, orientation: UIImageOrientation.right)

    self.tempImageView.image = image

}

我的猜测是:我应该使用什么来改变它?

谢谢。

4 个答案:

答案 0 :(得分:37)

在iOS 11中,你应该这样使用:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.postvu">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <uses-feature android:name="android.hardware.camera2">    </uses-feature>
                <uses-permission     android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
                <uses-permission android:name="android.permission.CAMERA"></uses-permission>
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".Main2Activity"></activity>
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.example.android.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths"></meta-data>
        </provider>
    </application>

</manifest>

答案 1 :(得分:10)

感谢@Vini应用程序,我尝试了它为我工作的代码,我发布了我的代码用于图像捕获和处理,希望这将帮助那些在他们的应用程序中需要类似功能的人。

首先你需要设置你的视频捕捉设备,搜索谷歌这里是一个例子https://gist.github.com/tad-iizuka/fc35bc7835920c0b8b84e316f83e3a40

确保您需要在顶部

定义photoSetting
...
var photoSetting = AVCapturePhotoSettings()
...

viewDidLoad()viewWillAppear()

中配置照片设置
            // Configure camera
        photoSetting = AVCapturePhotoSettings.init(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])
        photoSetting.isAutoStillImageStabilizationEnabled = true
        photoSetting.flashMode = .off

然后使用以下函数处理缓冲的图像数据

     func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {

    // Check if there is any error in capturing
    guard error == nil else {
        print("Fail to capture photo: \(String(describing: error))")
        return
    }

    // Check if the pixel buffer could be converted to image data
    guard let imageData = photo.fileDataRepresentation() else {
        print("Fail to convert pixel buffer")
        return
    }

    // Check if UIImage could be initialized with image data
    guard let capturedImage = UIImage.init(data: imageData , scale: 1.0) else {
        print("Fail to convert image data to UIImage")
        return
    }

    // Get original image width/height
    let imgWidth = capturedImage.size.width
    let imgHeight = capturedImage.size.height
    // Get origin of cropped image
    let imgOrigin = CGPoint(x: (imgWidth - imgHeight)/2, y: (imgHeight - imgHeight)/2)
    // Get size of cropped iamge
    let imgSize = CGSize(width: imgHeight, height: imgHeight)

    // Check if image could be cropped successfully
    guard let imageRef = capturedImage.cgImage?.cropping(to: CGRect(origin: imgOrigin, size: imgSize)) else {
        print("Fail to crop image")
        return
    }

    // Convert cropped image ref to UIImage
    imageToSave = UIImage(cgImage: imageRef, scale: 1.0, orientation: .down)
    UIImageWriteToSavedPhotosAlbum(imageToSave, nil, nil, nil)

    // Stop video capturing session (Freeze preview)
    captureSession.stopRunning()
}

在此功能中,像素缓冲区将以photoSetting指定的格式转换为图像数据,然后裁剪为您想要的大小。

您可以在IB中创建一个按钮来调用上面的捕捉功能

@IBAction func onTakePhoto(_ sender: UIButton) {
    if let videoConnection = videoOutput.connection(with: AVMediaType.video) {
        // Adjust the orientaion of captured image
        let capturePhotoSetting = AVCapturePhotoSettings.init(from: photoSetting)
        videoConnection.videoOrientation = (previewLayer.connection?.videoOrientation)!
        // Save captured photo to system album
        self.videoOutput.capturePhoto(with: capturePhotoSetting, delegate: self)
    }
}

答案 2 :(得分:0)

对于iOS 11.0及更低版本,我处理了

var photoOutput : AVCapturePhotoOutput?

if #available(iOS 11.0, *)
{
                    photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format:[AVVideoCodecKey:AVVideoCodecType.jpeg])], completionHandler: nil)
} 

else
{
                    photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format:[AVVideoCodecKey:AVVideoCodecJPEG])], completionHandler: nil)
}

答案 3 :(得分:0)

使用此代码(Swift 5),对我来说效果很好。

func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    guard let imageData = photo.fileDataRepresentation() else { return }
    let previewImage = UIImage(data: imageData)
}