设备相机数据(不是图像,而是实际相机属性)

时间:2017-10-30 16:41:20

标签: ios swift camera

我需要访问我的设备相机数据(不是图像数据!已经有了)。例如,“针孔”fx& fy&我可能得到的任何其他东西。

目前,我正在使用AVFoundation的'AVCaptureSession'和自定义UI。但之前我使用了'UIImagePickerController',它有一个名为

的委托方法
imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])

我能够从“信息”字典中检索拍摄的照片。它还给了我关于相机和相机的非常详细的信息。它的能力。就目前而言,我不知道在'AVCaptureSession'摄影期间如何检索这些相同的详细信息。请帮忙

1 个答案:

答案 0 :(得分:1)

您需要使用AVCapturePhotoOutput而不是AVCaptureStillImageOutput。

首先,下面的代码需要您的类

中的以下变量
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

在AVSession设置中添加照片输出

// 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类需要设置如下

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数据