在 Swift 中拍照并保存到照片库

Posted

技术标签:

【中文标题】在 Swift 中拍照并保存到照片库【英文标题】:Take a photo and save to photo library in Swift 【发布时间】:2016-11-28 22:47:03 【问题描述】:

我有一个“拍照”按钮,当按下它时,它会打开相机,你拍照,当你选择“使用照片”时,我希望它保存到照片库中。

除了保存到图书馆之外,我什么都能做。这是我必须打开相机的代码:

【问题讨论】:

Swift 4 版本在这里:***.com/questions/31582222/… 请添加代码而不是图片 【参考方案1】:

使用以下代码获取从照片库中获取的图像并保存在照片库中。

Swift 3.1 & 4.0 版本的代码支持:

首先,我们必须在 Project 的 .plist 文件中设置 Permissions:-

1) 相机

<key>NSCameraUsageDescription</key>
<string>This app will use camera.</string>

2) 图片库

<key>NSPhotoLibraryUsageDescription</key>
<string>You can select photos to attach to reports.</string>

3) 保存到照片库

<key>NSPhotoLibraryAddUsageDescription</key>
<string>Please allow access to save photo in your photo library</string>

我们需要打开 .pilst 文件作为 Source code 类型然后在里面添加 permissions -


之后


import UIKit

class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate  

    @IBOutlet weak var imageTake: UIImageView!

  var imagePicker: UIImagePickerController!
    override func viewDidLoad() 
        super.viewDidLoad()
    

    //MARK: - Take image
    @IBAction func takePhoto(_ sender: UIButton) 
        imagePicker =  UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.sourceType = .camera
        present(imagePicker, animated: true, completion: nil)
    

    //MARK: - Saving Image here
    @IBAction func save(_ sender: AnyObject) 
        UIImageWriteToSavedPhotosAlbum(imageTake.image!, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)
    

    //MARK: - Add image to Library
    func image(_ image: UIImage, didFinishSavingWithError error: Error?, 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: "Saved!", message: "Your altered image has been saved to your photos.", preferredStyle: .alert)
            ac.addAction(UIAlertAction(title: "OK", style: .default))
            present(ac, animated: true)
        
    

    //MARK: - Done image capture here
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) 
         imagePicker.dismiss(animated: true, completion: nil)
        imageTake.image = info[UIImagePickerControllerOriginalImage] as? UIImage
    



Swift 4.2 代码更新 -

 class ViewController: UIViewController, UINavigationControllerDelegate  

    @IBOutlet weak var imageTake: UIImageView!
    var imagePicker: UIImagePickerController!

    enum ImageSource 
        case photoLibrary
        case camera
    

    override func viewDidLoad() 
        super.viewDidLoad()
    

    //MARK: - Take image
    @IBAction func takePhoto(_ sender: UIButton) 
        guard UIImagePickerController.isSourceTypeAvailable(.camera) else 
            selectImageFrom(.photoLibrary)
            return
        
        selectImageFrom(.camera)
    

    func selectImageFrom(_ source: ImageSource)
        imagePicker =  UIImagePickerController()
        imagePicker.delegate = self
        switch source 
        case .camera:
            imagePicker.sourceType = .camera
        case .photoLibrary:
            imagePicker.sourceType = .photoLibrary
        
        present(imagePicker, animated: true, completion: nil)
    

    //MARK: - Saving Image here
    @IBAction func save(_ sender: AnyObject) 
        guard let selectedImage = imageTake.image else 
            print("Image not found!")
            return
        
        UIImageWriteToSavedPhotosAlbum(selectedImage, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)
    

    //MARK: - Add image to Library
    @objc func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) 
        if let error = error 
            // we got back an error!
            showAlertWith(title: "Save error", message: error.localizedDescription)
         else 
            showAlertWith(title: "Saved!", message: "Your image has been saved to your photos.")
        
    

    func showAlertWith(title: String, message: String)
        let ac = UIAlertController(title: title, message: message, preferredStyle: .alert)
        ac.addAction(UIAlertAction(title: "OK", style: .default))
        present(ac, animated: true)
    
 

 extension ViewController: UIImagePickerControllerDelegate

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
        imagePicker.dismiss(animated: true, completion: nil)
        guard let selectedImage = info[.originalImage] as? UIImage else 
            print("Image not found!")
            return
        
        imageTake.image = selectedImage
    

【讨论】:

完美!它工作得很好:-)。现在上传到 Firebase 存储 谢谢。它节省了我的时间。 完美!!效果很好 感谢您的精彩回答 好方法。感谢您在本教程中拍照并在图库中获取图像。【参考方案2】:

Anand Nimje 为 Swift 4 更新了答案

class ImageCaptureViewController: UIViewController,UINavigationControllerDelegate,  UIImagePickerControllerDelegate 

@IBOutlet weak var takeImage: UIImageView!
var imagePicker: UIImagePickerController!

@IBAction func takePhoto(_ sender: UIButton) 
    imagePicker = UIImagePickerController()
    imagePicker.delegate = self
    imagePicker.sourceType = .camera
    present(imagePicker, animated: true, completion: nil)


@IBAction func savePhoto(_ sender: UIButton) 
    UIImageWriteToSavedPhotosAlbum(takeImage.image!, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)


@objc func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) 
    if let error = 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: "Saved!", message: "Your altered image has been saved to your photos.", preferredStyle: .alert)
        ac.addAction(UIAlertAction(title: "OK", style: .default))
        present(ac, animated: true)
    


func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) 
    imagePicker.dismiss(animated: true, completion: nil)
    takeImage.image = info[UIImagePickerControllerOriginalImage] as? UIImage


【讨论】:

【参考方案3】:

Swift 3.0

class PhotoViewController: UIViewController, UIGestureRecognizerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate 

创建你的 UIImageView outlets 和 UIImagePickerController

@IBOutlet weak var userPhotoImageView: UIImageView!
var pickerController = UIImagePickerController()
var imageView = UIImage()

这里我使用 Tapgesture 来点击 UIImageView

     in viewDidLoad 

    let imageTapGesture = UITapGestureRecognizer(target: self, action: #selector(tapUserPhoto(_:)))
    imageTapGesture.delegate = self
    userPhotoImageView.addGestureRecognizer(imageTapGesture)
    imageTapGesture.numberOfTapsRequired = 1
    userPhotoImageView.isUserInteractionEnabled = true
    pickerController.delegate = self
    func tapUserPhoto(_ sender: UITapGestureRecognizer)
    let alertViewController = UIAlertController(title: "", message: "Choose your option", preferredStyle: .actionSheet)
    let camera = UIAlertAction(title: "Camera", style: .default, handler:  (alert) in
        self.openCamera()
    )
    let gallery = UIAlertAction(title: "Gallery", style: .default)  (alert) in
        self.openGallary()
    
    let cancel = UIAlertAction(title: "Cancel", style: .cancel)  (alert) in

    
    alertViewController.addAction(camera)
    alertViewController.addAction(gallery)
    alertViewController.addAction(cancel)
    self.present(alertViewController, animated: true, completion: nil)

  func openCamera() 
    if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera) 
        pickerController.delegate = self
        self.pickerController.sourceType = UIImagePickerControllerSourceType.camera
        pickerController.allowsEditing = true
        self .present(self.pickerController, animated: true, completion: nil)
    
    else 
        let alertWarning = UIAlertView(title:"Warning", message: "You don't have camera", delegate:nil, cancelButtonTitle:"OK", otherButtonTitles:"")
        alertWarning.show()
    

func openGallary() 
    if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) 
        pickerController.delegate = self
        pickerController.sourceType = UIImagePickerControllerSourceType.photoLibrary
        pickerController.allowsEditing = true
        self.present(pickerController, animated: true, completion: nil)
    

public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) 

    imageView = info[UIImagePickerControllerEditedImage] as! UIImage
    userPhotoImageView.contentMode = .scaleAspectFill
    userPhotoImageView.image = imageView
    dismiss(animated:true, completion: nil)

public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) 
    print("Cancel")

【讨论】:

【参考方案4】:
import UIKit

class photoPickerController: UIViewController,UINavigationControllerDelegate

@IBOutlet weak var imageTake: UIImageView!

var imagePicker: UIImagePickerController!
override func viewDidLoad() 
    super.viewDidLoad()



@IBAction func takePhoto(_ sender: UIButton) 

    imagePicker =  UIImagePickerController()
    imagePicker.delegate = self
    imagePicker.sourceType = .camera
    present(imagePicker, animated: true, completion: nil)



@IBAction func saveToLibrary(_ sender: AnyObject) 
    UIImageWriteToSavedPhotosAlbum(imageTake.image!, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)
    


extension photoPickerController :  UIImagePickerControllerDelegate  

func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) 
    if let error = error 
        // we got back an error!
        let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
     else 
        let alert = UIAlertController(title: "Saved!", message: "Image saved successfully", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
    


func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) 
    imagePicker.dismiss(animated: true, completion: nil)
    imageTake.image = info[UIImagePickerControllerOriginalImage] as? UIImage
    

【讨论】:

【参考方案5】:

斯威夫特 5:

捕获和保存图像的正确流程。

// 0. Add `NSCameraUsageDescription`, `NSPhotoLibraryUsageDescription` and `NSPhotoLibraryAddUsageDescription` in Info.plist
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate 
    
    /// the captured image
    private var image: UIImage?
    
    // 1. Check for permissions first
    /// "Take Photo" button action handler
    ///
    /// - parameter sender: the button
    @IBAction func takePhoto(_ sender: UIButton) 
        if AVCaptureDevice.authorizationStatus(for: .video) ==  .authorized 
            self.showPickerWithSourceType(UIImagePickerController.SourceType.camera)
         else 
            AVCaptureDevice.requestAccess(for: .video, completionHandler:  (granted: Bool) in
                DispatchQueue.main.async 
                    if granted 
                        self.showPickerWithSourceType(UIImagePickerController.SourceType.camera)
                     else 
                        self.showAlert("No access to camera", message: "You need to grant permissions to camera to take a picture.")
                    
                
            )
        
    
    
    // 2. Open photo capture
    /// Show image picker
    /// - Parameter sourceType: the type of the source
    private func showPickerWithSourceType(_ sourceType: UIImagePickerController.SourceType) 
        var vc: UIViewController!
        if UIImagePickerController.isSourceTypeAvailable(sourceType) 
            let imagePicker = UIImagePickerController()
            imagePicker.delegate = self
            imagePicker.mediaTypes = [kUTTypeImage as String]       // if you also need a video, then use [kUTTypeImage as String, kUTTypeMovie as String]
            imagePicker.sourceType = sourceType
            imagePicker.videoQuality = UIImagePickerController.QualityType.typeMedium
            vc = imagePicker
        
        else 
            let alert = UIAlertController(title: "Error", message: "This feature is supported on real devices only", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
            vc = alert
        
        DispatchQueue.main.async 
            UIViewController.getCurrentViewController()?.present(vc, animated: true, completion: nil)
        
    
    
    // 3. Temporary save image in `self.image`
    /// Image selected/captured
    /// - Parameters:
    ///   - picker: the picker
    ///   - info: the info
    public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) 
        if let mediaType = info[UIImagePickerController.InfoKey.mediaType] 
            if (mediaType as AnyObject).description == kUTTypeImage as String 
                if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage 
                    self.image = image
                
            
        
        picker.dismiss(animated: true, completion: nil)
    
    
    // 4. Save image
    /// "Save" button action handler
    ///
    /// - parameter sender: the button
    @IBAction func saveImageButtonAction(_ sender: Any) 
        guard let image = self.image else  return 
        UIImageWriteToSavedPhotosAlbum(image, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)
    
    
    
    // Called when image save is complete (with error or not)
    @objc func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) 
        if let error = error 
            print("ERROR: \(error)")
        
        else 
            self.showAlert("Image saved", message: "The iamge is saved into your Photo Library.")
        
    
    
    /// Show popup with title and message
    /// - Parameters:
    ///   - title: the title
    ///   - message: the message
    private func showAlert(_ title: String, message: String) 
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    

【讨论】:

【参考方案6】:

事实上你可以把它添加到你的代码中,它会保存:

UIImageWriteToSavedPhotosAlbum(/* your image */, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) 

     imagePicker.dismiss(animated: true, completion: nil)
    imageTake.image = info[UIImagePickerControllerOriginalImage] as? UIImage


【讨论】:

以上是关于在 Swift 中拍照并保存到照片库的主要内容,如果未能解决你的问题,请参考以下文章

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

如何使用swift拍照并保存到本地应用程序

如何拍照,保存并在Android中获取照片

将 arkit 快照直接保存到照片库 swift 4

如何在 Android 中拍照、保存和获取照片

使用edsdk 2.8拍照并直接将图像保存到PC