AVCapturePhotoOutput을 사용해야하며 AVCaptureStillImageOutput은 사용하지 않아야합니다.
먼저 아래 코드는 클래스에 다음 변수를 필요로 AVSession 설정에서 사진 출력을 추가
private let photoOutput = AVCapturePhotoOutput()
private var inProgressPhotoCaptureDelegates = [Int64 : AVPhotoCaptureDelegate]()
private let sessionQueue = DispatchQueue(label: "session queue", attributes: [], target: nil) // Communicate with the session
private var videoDeviceOrientation : AVCaptureVideoOrientation = .portrait // this needs updated as the device orientation changes
// Add photo output.
if session.canAddOutput(photoOutput) {
session.addOutput(photoOutput)
self.photoOutput.isHighResolutionCaptureEnabled = true
}
귀하의 capturePhoto()
func capturePhoto(aspectRatio : Float, metaData : NSDictionary?) {
sessionQueue.async {
// Update the photo output's connection to match the video orientation of the video preview layer.
if let photoOutputConnection = self.photoOutput.connection(with: AVMediaType.video) {
photoOutputConnection.videoOrientation = self.videoDeviceOrientation
}
// Capture a JPEG photo with flash set to off and high resolution photo enabled.
let photoSettings = AVCapturePhotoSettings()
photoSettings.flashMode = .off
photoSettings.isHighResolutionPhotoEnabled = true
if photoSettings.availablePreviewPhotoPixelFormatTypes.count > 0 {
photoSettings.previewPhotoFormat = [kCVPixelBufferPixelFormatTypeKey as String : photoSettings.availablePreviewPhotoPixelFormatTypes.first!]
}
// Use a separate object for the photo capture delegate to isolate each capture life cycle.
let photoCaptureDelegate = MyAVPhotoCaptureDelegate(completed: { [unowned self] photoCaptureDelegate in
// When the capture is complete, remove a reference to the photo capture delegate so it can be deallocated.
self.sessionQueue.async { [unowned self] in
self.inProgressPhotoCaptureDelegates[photoCaptureDelegate.requestedPhotoSettings.uniqueID] = nil
}
)
/*
The Photo Output keeps a weak reference to the photo capture delegate so
we store it in an array to maintain a strong reference to this object
until the capture is completed.
*/
self.inProgressPhotoCaptureDelegates[photoCaptureDelegate.requestedPhotoSettings.uniqueID] = photoCaptureDelegate
self.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureDelegate)
}
}
을 다음과 같이 기능을 설정해야
capturePhoto() 함수에서 참조되는 MyAVPhotoCaptureDelegate 클래스 abov e는 다음과 같이 설정해야합니다.
class MyAVPhotoCaptureDelegate: NSObject, AVCapturePhotoCaptureDelegate {
init(completed: @escaping (AVPhotoCaptureDelegate) ->()) {
self.completed = completed
}
private func didFinish() {
completed(self)
}
func photoOutput(_ captureOutput: AVCapturePhotoOutput, willCapturePhotoFor resolvedSettings: AVCaptureResolvedPhotoSettings) {
}
func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?, previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {
if let photoSampleBuffer = photoSampleBuffer {
let propertiesDictionary = NSMutableDictionary()
if let exif = CMGetAttachment(photoSampleBuffer, kCGImagePropertyExifDictionary as NSString, nil) {
if let exifDictionary = exif as? NSMutableDictionary {
// view exif data
}
}
photoData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer)
}
else {
print("Error capturing photo: \(String(describing:error))")
return
}
}
func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishCaptureFor resolvedSettings: AVCaptureResolvedPhotoSettings, error: Error?) {
// Use PHPhotoLibrary to save photoData to photo library
...
}
private let completed : (MyAVPhotoCaptureDelegate) ->()
}
이 코드의 대부분은 내 구현의 특정 사항이 제거 된 AVCam의 버전에서 가져온 것입니다. 사진 라이브러리에 저장하는 코드는 생략했지만 샘플 코드에서 추출 할 수 있습니다. 당신은 "exif 데이터보기"라고 말한 지점에서 exif 데이터를 볼 수 있습니다.
AVCapturePhotoCaptureDelegate 클래스를 설정 했습니까? – Spads
Nope. 당신이 그것을 언급 할 때까지 그것에 대해 알지도 못했어요 – Krekin
AVFoundation을 사용한다면, 어떻게 이미지를 저장하고 있습니까? 어떤 시점에서 AVCapturePhotoOutput.capturePhoto (AVCapturePhotoSettings, 대리자 : AVCapturePhotoCaptureDelegate)를 호출해야합니다. – Spads