使用Photos Framework获取相机拍摄的照片的URL

问题描述:

我有一个应用程序使用UIImagePickerController从相机和照片库中检索照片。 在图像选择器代理中,我只想保存拾取图像的NSURL(UIImagePickerControllerReferenceURL)以节省内存。当用户稍后需要查看图像时,我直接从照片库中使用PHCachingImageManager加载它。使用Photos Framework获取相机拍摄的照片的URL

现在 - 这整件事情与用户从图书馆中选择的图片一起使用效果很好,但与照相机直接拍摄的图片无关(因为没有网址)。我目前正试图用PHAsset保存图片,但我不知道如何获取保存图片的NSURL。

这是我去过最多:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) 
{ 
    picker.dismissViewControllerAnimated(true, completion: nil) 

    let pickedImage = info[UIImagePickerControllerOriginalImage] as! UIImage 

    if picker.sourceType == .Camera 
    { 
     // When taking a picture with the camera, store it in the user roll 
     PHPhotoLibrary.sharedPhotoLibrary().performChanges(
      {() -> Void in 

       // save the image 
       PHAssetCreationRequest.creationRequestForAssetFromImage(pickedImage) 

       // TODO how to get the asset url 

      }, completionHandler: 
      { (finished, error) -> Void in 
       if (finished) 
       { 

       } 
      } 
     ) 

    } 
    else 
    { 
     let pickedImageUrl: NSURL? = info[UIImagePickerControllerReferenceURL] as? NSURL 

     currentImageUrl = pickedImageUrl 

     currentImage = pickedImage 

     toggleImageInfoView(true) 
     toggleMapState(true) 
    } 


} 

任何想法如何得到保存的图片的网址是什么?

最佳, 乔治

+0

Georg,您是否找到解决方案?我在这里面临同样的问题,并没有找到任何解决方案... – gersonmendes

更新:好像我找到了答案这个问题。

第1步:我将图像保存到相机

UIImageWriteToSavedPhotosAlbum(image.image, self, #selector(cameraImageSavedAsynchronously), nil) 

这是异步完成的,所以一定要确保当操作完成设置选择。

步骤2:当操作完成后,我执行以下操作:

func fetchLastImage(completion: (localIdentifier: String?) -> Void) 
{ 
    let fetchOptions = PHFetchOptions() 
    fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] 
    fetchOptions.fetchLimit = 1 

    let fetchResult = PHAsset.fetchAssetsWithMediaType(.Image, options: fetchOptions) 
    if (fetchResult.firstObject != nil) 
    { 
     let lastImageAsset: PHAsset = fetchResult.firstObject as! PHAsset 
     completion(localIdentifier: lastImageAsset.localIdentifier) 
    } 
    else 
    { 
     completion(localIdentifier: nil) 
    } 
} 

予取与PHAsset相机胶卷的最后一个图像,并保存该图像的本地标识符。这不是一个URL,而是一个不会改变的唯一标识符。这样,您可以完美地访问保存的图像。

希望这可以帮助别人!

+0

什么应该传递在“localIdentifier” – Anny

+0

什么是localIdentifier字符串在这里,我怎么能调用这个方法? – 2017-05-16 09:47:35

我同意你的意见。

但是,如果图像的Exif具有较早的日期。

let fetchResult = PHAsset.fetchAssetsWithMediaType(.Image, options: fetchOptions) 
fetchResult.firstObject 

fetchResult.firstObject不是您刚保存的那个。

也许你可以修改fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)key: "modificationDate"

BTW,我发现了一个其他的方式:

__block PHObjectPlaceholder *placeholderAsset = nil; 
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ 
    PHAssetChangeRequest *newAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:url]; 
    newAssetRequest.location = location; 
    newAssetRequest.creationDate = [NSDate date]; 
    placeholderAsset = newAssetRequest.placeholderForCreatedAsset; 
} completionHandler:^(BOOL success, NSError *error) { 
    if(success){ 
     PHAsset *asset = [self getAssetFromlocalIdentifier:placeholderAsset.localIdentifier]; 
     completionBlock(asset, YES); 
    } else { 
     completionBlock(nil, NO); 
    } 
}]; 

可以得到新PHAsset。