获取UIImagePickerController选定的UIImage的URL

27
我想让用户从照片库中选择一张图片。因此,我正在使用UIImagePickerController进行选择。但在获取文件系统中它的初始URL时遇到了问题(我需要这个URL用于CKAsset)。
我的代码。
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
    let imageURL = info[UIImagePickerControllerReferenceURL] as NSURL
    let path = imageURL.path!
    let imageName = path.lastPathComponent
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
    let documentDirectory = paths.first as String!
    let localPath = documentDirectory + "/" + imageName

    let imageData = NSData(contentsOfFile: localPath)!
    let image = UIImage(data: imageData)!

    picker.dismissViewControllerAnimated(true, completion: nil)

}

imageURL看起来有点神秘。它描述了Asset URL,但不是文件系统中的URL,并且格式如下:assets-library://asset/asset.JPG?id=B6C0A21C-07C3-493D-8B44-3BA4C9981C25&ext=JPG

根据这个逻辑,路径/asset.JPG,其中asset.JPG是图片的名称。

然后我访问我的文档文件夹并尝试在那里找到一个具有以下路径的文件:

  

/Users/Eugene/Library/Developer/CoreSimulator/Devices/3C5E9A23-8220-4B37-BD14-F1E42EEC2C7C/data/Containers/Data/Application/20EBAAE2-6C6F-4651-A48F-16A222CCB3A2/Documents/asset.JPG

这个路径也很神秘,但似乎是一个不存在的图像的真实路径......没有任何路径为该路径的图像。这让我很困扰。

我需要从一开始保存图像吗?还是还有其他方法可以解决我的问题?

我已经查阅了几篇使用AssetsLibrary API的教程,但没有找到任何有用的解决方案。提前感谢您!

8个回答

41

好的,我已经解决了这个问题。

你只需要简单地获取图像 (info[UIImagePickerControllerOriginalImage] as UIImage) 并保存到指定目录即可。如果你只需要保存一张图片,它非常有效。代码如下:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
    let imageURL = info[UIImagePickerControllerReferenceURL] as NSURL
    let imageName = imageURL.path!.lastPathComponent
    let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as String
    let localPath = documentDirectory.stringByAppendingPathComponent(imageName)

    let image = info[UIImagePickerControllerOriginalImage] as UIImage
    let data = UIImagePNGRepresentation(image)
    data.writeToFile(localPath, atomically: true)

    let imageData = NSData(contentsOfFile: localPath)!
    let photoURL = NSURL(fileURLWithPath: localPath)
    let imageWithData = UIImage(data: imageData)!

    picker.dismissViewControllerAnimated(true, completion: nil)

}

3
你能否更新你关于Swift 2的答案?谢谢! - Peter Kreinz
6
无法在Swift 3中运行,我已将代码转换以使其编译,但返回的路径未指向所选图像。 - zumzum
对于Swift 3,请查看此解决方案:https://dev59.com/c2445IYBdhLWcg3wQoAj#43456006 - XueYu
@majorton,保存100张图片的最佳方法是什么? - aaisataev

15
SWIFT 4 中,您可以尝试这样做:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    
    
    if let imgUrl = info[UIImagePickerControllerImageURL] as? URL{
        let imgName = imgUrl.lastPathComponent
        let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
        let localPath = documentDirectory?.appending(imgName)
        
        let image = info[UIImagePickerControllerOriginalImage] as! UIImage
        let data = UIImagePNGRepresentation(image)! as NSData
        data.write(toFile: localPath!, atomically: true)
        //let imageData = NSData(contentsOfFile: localPath!)!
        let photoURL = URL.init(fileURLWithPath: localPath!)//NSURL(fileURLWithPath: localPath!)
        print(photoURL)
        
    }

    APPDEL.window?.rootViewController?.dismiss(animated: true, completion: nil)
}

5

对于Swift 5+;根据@Jaydip的回答

if let imgUrl = info[UIImagePickerController.InfoKey.imageURL] as? URL{
        let imgName = imgUrl.lastPathComponent
        let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
        let localPath = documentDirectory?.appending(imgName)

        let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
        let data = image.pngData()! as NSData
        data.write(toFile: localPath!, atomically: true)
        //let imageData = NSData(contentsOfFile: localPath!)!
        let photoURL = URL.init(fileURLWithPath: localPath!)//NSURL(fileURLWithPath: localPath!)
        print(photoURL)

    }

谢谢兄弟,它可以工作了。 - Bijender Singh Shekhawat

4
  func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
//this block of code grabs the path of the file   
let imageURL = info[UIImagePickerControllerReferenceURL] as NSURL
let imagePath =  imageURL.path!
let localPath = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent(imagePath)

 //this block of code adds data to the above path
 let path = localPath.relativePath!
 let imageName = info[UIImagePickerControllerOriginalImage] as UIImage
 let data = UIImagePNGRepresentation(imageName)
 data?.writeToFile(imagePath, atomically: true)

//this block grabs the NSURL so you can use it in CKASSET
 let photoURL = NSURL(fileURLWithPath: path)
 }

@Peter Kreinz,希望这个能帮到你。 - DHuang

2

swift 4.2

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    
    //obtaining saving path
    let fileManager = FileManager.default
    let documentsPath = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first
    let imagePath = documentsPath?.appendingPathComponent("image.jpg")
    
    // extract image from the picker and save it
    if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
        
        let imageData = pickedImage.jpegData(compressionQuality: 0.75)
        try! imageData?.write(to: imagePath!)
    }
}

谢谢


2
在Swift 4中,
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {        
    if let imgUrl = info[UIImagePickerControllerReferenceURL] as? URL{

        let imgName = imgUrl.lastPathComponent
        let documentDirectory = NSTemporaryDirectory()
        let localPath = documentDirectory.appending(imgName)

        let image = info[UIImagePickerControllerOriginalImage] as! UIImage
        let data = UIImageJPEGRepresentation(image, 0.3)! as NSData
        data.write(toFile: localPath, atomically: true)
        let photoURL = URL.init(fileURLWithPath: localPath)

    }

}

1
FYI - UIImagePickerController.InfoKey.referenceURL 在 iOS 11.0 中已被弃用。 - JaredH

2

请检查这个解决方案。

 import AssetsLibrary  

     func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
          self.imagePicker = picker
          if let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
            let controller = CropViewController(image: selectedImage )
            controller.delegate = self
            picker.presentViewController(controller, animated: true, completion: nil)
          }

       else if let imageUrl = info[UIImagePickerControllerReferenceURL] as? NSURL{
          let assetLibrary = ALAssetsLibrary()
          assetLibrary.assetForURL(imageUrl , resultBlock: { (asset: ALAsset!) -> Void in
            if let actualAsset = asset as ALAsset? {
              let assetRep: ALAssetRepresentation = actualAsset.defaultRepresentation()
              let iref = assetRep.fullResolutionImage().takeUnretainedValue()
              let image = UIImage(CGImage: iref)
              let controller = CropViewController(image: image)
              controller.delegate = self
              picker.presentViewController(controller, animated: true, completion: nil)
            }
            }, failureBlock: { (error) -> Void in
          })
        }
      }

1
let imgUrl = info[UIImagePickerController.InfoKey.imageURL] as? URL

简单而又精准的解决方案!这对我很有效。谢谢。 - newProgramm3r

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接