iOS UIImagePickerController如何从相机拍摄图像后立即保存图像

时间:2018-07-25 12:14:47

标签: ios swift uiimagepickercontroller

使用UIImagePickerController并获取其URL时,我很难存储从相机拍摄的图像。

检查日志,我认为是因为拍摄的图像在手机上没有保存的路径吗?

let imageUrl          = info[UIImagePickerControllerImageURL] as? NSURL // logs show nil here
...
let localPath         = photoURL.appendingPathComponent(imageName!) // crashes here due to forced unwrap of imageName (nil)

我想知道如何解决这个问题?我已经咨询了其他答案,但是都无法解决(过时的库或其他问题)。

更完整的代码:

func openCamera() {
        if UIImagePickerController.isSourceTypeAvailable(.camera) {
            let imagePickerController = UIImagePickerController()
            imagePickerController.delegate = self
            imagePickerController.sourceType = .camera;
            imagePickerController.allowsEditing = false
            present(imagePickerController, animated: true, completion: nil)
        }
    }


func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
            fatalError("error message")
        }

        let image = info[UIImagePickerControllerOriginalImage] as! UIImage
        let imageUrl          = info[UIImagePickerControllerImageURL] as? NSURL // logs show nil here
        let imageName         = imageUrl?.lastPathComponent
        let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
        let photoURL          = NSURL(fileURLWithPath: documentDirectory)
        let localPath         = photoURL.appendingPathComponent(imageName!) // crashes here due to forced unwrap of imageName (nil)

        if !FileManager.default.fileExists(atPath: localPath!.path) {
            do {
                try UIImageJPEGRepresentation(image, 1.0)?.write(to: localPath!)
                print("file saved")
            }catch {
                print("error saving file")
            }
        }
        else {
            print("file already exists")
        }

        ...
        dismiss(animated: true, completion: nil)
    }

2 个答案:

答案 0 :(得分:0)

有一个非常简单的功能:

UIImageWriteToSavedPhotosAlbum(chosenImage, nil, nil, nil)

但是我也创建了帮助程序类来解决这个问题。多亏了这个助手,您可以将照片保存在指定的相册中

import Foundation
import Photos

final class PhotoAlbumHelper: NSObject {

    static let albumName = "AppAlbum"
    static let shared = PhotoAlbumHelper()

    var assetCollection: PHAssetCollection?
    var failedPhotos = [UIImage]()

    func fetchAssetCollectionForAlbum() -> PHAssetCollection? {
        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "title = %@", PhotoAlbumHelper.albumName)
        let collections = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: fetchOptions)

        if let collection = collections.firstObject {
            return collection
        }
        return nil
    }

    func createAlbum() {
        PHPhotoLibrary.shared().performChanges({
            PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: PhotoAlbumHelper.albumName) // create an asset collection with the album name
        }) { [weak self] success, error in
            if success {
                guard let `self` = self else { return }
                self.assetCollection = self.fetchAssetCollectionForAlbum()
                while self.failedPhotos.count > 0 {
                    self.saveImage(self.failedPhotos.removeFirst())
                }
            } else {
                print(error)
            }
        }
    }

    func saveImage(_ image: UIImage) {
        assetCollection = fetchAssetCollectionForAlbum()
        if assetCollection == nil {
            failedPhotos.append(image)
            createAlbum()
            return
        }
        guard let album = assetCollection else { return }
        PHPhotoLibrary.shared().performChanges({
            let creationRequest = PHAssetChangeRequest.creationRequestForAsset(from: image)
            guard let addAssetRequest = PHAssetCollectionChangeRequest(for: album) else { return }
            let index = IndexSet(integer: 0)
            addAssetRequest.insertAssets([creationRequest.placeholderForCreatedAsset!] as NSArray, at: index)
        }, completionHandler: { success, error in
            if !success {
                print(error)
            }
        })
    }
}

答案 1 :(得分:0)

根据文档:

  

包含原始图像和编辑图像的字典(如果已选择图像);或电影的文件系统URL(如果已选择电影)。该词典还包含任何相关的编辑信息。该词典的键在“编辑信息键”中列出。

Link to Documentation

您无法获取URL(或者您不应获取)。  但是您可以拥有图像本身(在UIImagePickerControllerEditedImageUIImagePickerControllerOriginalImage中。