如何拍照并同时保存(swift3)

Posted

技术标签:

【中文标题】如何拍照并同时保存(swift3)【英文标题】:How to take photo and save it at the same time (swift3) 【发布时间】:2017-02-11 21:53:31 【问题描述】:

现在我的代码有 1 个视图、1 个按钮和 1 个图像视图。目前,代码拍摄照片并放置在 uniimageview 上。如何编写代码以便每次拍摄照片时都会将其保存到照片库中。我已经更新了 plist 设置。

 import UIKit
import AVFoundation

class ViewController: UIViewController,AVCapturePhotoCaptureDelegate  

var captureSesssion : AVCaptureSession!
var cameraOutput : AVCapturePhotoOutput!
var previewLayer : AVCaptureVideoPreviewLayer!

@IBOutlet weak var capturedImage: UIImageView!
@IBOutlet weak var previewView: UIView!

override func viewDidLoad() 
    super.viewDidLoad()
    captureSesssion = AVCaptureSession()
    captureSesssion.sessionPreset = AVCaptureSessionPresetPhoto
    cameraOutput = AVCapturePhotoOutput()

    let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

    if let input = try? AVCaptureDeviceInput(device: device) 
        if (captureSesssion.canAddInput(input)) 
            captureSesssion.addInput(input)
            if (captureSesssion.canAddOutput(cameraOutput)) 
                captureSesssion.addOutput(cameraOutput)
                previewLayer = AVCaptureVideoPreviewLayer(session: captureSesssion)
                previewLayer.frame = previewView.bounds
                previewView.layer.addSublayer(previewLayer)
                captureSesssion.startRunning()
            
         else 
            print("issue here : captureSesssion.canAddInput")
        
     else 
        print("some problem here")
    


// Take picture button
@IBAction func didPressTakePhoto(_ sender: UIButton) 
    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
    cameraOutput.capturePhoto(with: settings, delegate: self)



// callBack from take picture
func capture(_ captureOutput: AVCapturePhotoOutput,  didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?,  previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings:  AVCaptureResolvedPhotoSettings, bracketSettings:   AVCaptureBracketedStillImageSettings?, error: Error?) 

    if let error = error 
        print("error occure : \(error.localizedDescription)")
    

    if  let sampleBuffer = photoSampleBuffer,
        let previewBuffer = previewPhotoSampleBuffer,
        let dataImage =  AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer:  sampleBuffer, previewPhotoSampleBuffer: previewBuffer) 
        print(UIImage(data: dataImage)?.size as Any)

        let dataProvider = CGDataProvider(data: dataImage as CFData)
        let cgImageRef: CGImage! = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: .defaultIntent)
        let image = UIImage(cgImage: cgImageRef, scale: 1.0, orientation: UIImageOrientation.right)

        self.capturedImage.image = image
     else 
        print("some error here")
    


// This method you can use somewhere you need to know camera permission   state
func askPermission() 
    print("here")
    let cameraPermissionStatus =  AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)

    switch cameraPermissionStatus 
    case .authorized:
        print("Already Authorized")
    case .denied:
        print("denied")

        let alert = UIAlertController(title: "Sorry :(" , message: "But  could you please grant permission for camera within device settings",  preferredStyle: .alert)
        let action = UIAlertAction(title: "Ok", style: .cancel,  handler: nil)
        alert.addAction(action)
        present(alert, animated: true, completion: nil)

    case .restricted:
        print("restricted")
    default:
        AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: 
            [weak self]
            (granted :Bool) -> Void in

            if granted == true 
                // User granted
                print("User granted")
                DispatchQueue.main.async()
                    //Do smth that you need in main thread   
                 
            
            else 
                // User Rejected
                print("User Rejected")

                DispatchQueue.main.async()
                    let alert = UIAlertController(title: "WHY?" , message:  "Camera it is the main feature of our application", preferredStyle: .alert)
                    let action = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
                    alert.addAction(action)
                    self?.present(alert, animated: true, completion: nil)  
                 
            
        );
    


【问题讨论】:

【参考方案1】:

如果您想保存照片,您只需调用UIImageWriteToSavedPhotosAlbum 并在现有代码中将图像对象传递给它

示例代码

    func capture(_ captureOutput: AVCapturePhotoOutput,  didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?,  previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings:  AVCaptureResolvedPhotoSettings, bracketSettings:   AVCaptureBracketedStillImageSettings?, error: Error?) 

        if let error = error 
            print("error occure : \(error.localizedDescription)")
        

        if  let sampleBuffer = photoSampleBuffer,
            let previewBuffer = previewPhotoSampleBuffer,
            let dataImage =  AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer:  sampleBuffer, previewPhotoSampleBuffer: previewBuffer) 
            print(UIImage(data: dataImage)?.size as Any)

            let dataProvider = CGDataProvider(data: dataImage as CFData)
            let cgImageRef: CGImage! = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: .defaultIntent)
            let image = UIImage(cgImage: cgImageRef, scale: 1.0, orientation: UIImageOrientation.right)

            self.capturedImage.image = image

            //Add: Save image object to photo album
//            UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) //
            UIImageWriteToSavedPhotosAlbum(image, self, #selector(self.image(_:didFinishSavingWithError:contextInfo:)), nil)
         else 
            print("some error here")
        
    

    func image(_ image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeRawPointer) 
        if let error = error 
            // we got back an error!
            let ac = UIAlertController(title: "Save error", message: error.localizedDescription, preferredStyle: .alert)
            ac.addAction(UIAlertAction(title: "OK", style: .default))
            present(ac, animated: true)
         else 
            let ac = UIAlertController(title: "Image Saved!", message: "Your image has been saved to your photos.", preferredStyle: .alert)
            ac.addAction(UIAlertAction(title: "OK", style: .default))
            present(ac, animated: true)
        
    

我已在您需要在代码中添加的行上方添加了注释。

【讨论】:

以上是关于如何拍照并同时保存(swift3)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Laravel 中调整图像大小并同时将数据保存在数据库中

如何上传图片Url上传到Fire Storage并同时保存在fireStore中使用Java

在 pyqt5 gui 中显示 matplotlib 动画图并同时保存在 mp4 中的问题

如何在不保存/显示图像的情况下拍照

无法写入文件名并同时单击“保存”按钮...VBA代码

如何在 iOS 上拍照并保存在 SQLite 数据库中