在 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 中拍照并保存到照片库的主要内容,如果未能解决你的问题,请参考以下文章