我的应用程序中有自定义相机并且工作正常,但在新更新后我收到此错误:
' 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
}
我的猜测是:我应该使用什么来改变它?
谢谢。
答案 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)
}