使用 Photos Framework 获取相机拍摄的照片 URL
Getting the URL of picture taken by camera with Photos Framework
我有一个应用程序使用 UIImagePickerController 从相机和照片库中检索照片。
在图像选择器委托中,我只想保存所选图像的 NSURL (UIImagePickerControllerReferenceURL) 以节省内存。当用户稍后需要查看图像时,我直接从照片库使用 PHCachingImageManager 加载它。
现在 - 这整个过程对于用户从库中选择的图片非常有效,但对于相机直接拍摄的图片则效果不佳(因为没有 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)
}
}
关于如何获取已保存图片的 url 有什么想法吗?
最好的,
乔治
更新:我好像找到了这个问题的答案。
第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,而是一个不会改变的唯一标识符。这样,您就可以完美访问保存的图片了。
希望这对其他人有帮助!
我同意你的看法。
但是,如果图像的 Exif 具有更早的日期。
let fetchResult = PHAsset.fetchAssetsWithMediaType(.Image, options: fetchOptions)
fetchResult.firstObject
fetchResult.firstObject不是你刚刚保存的那个
或许你可以将fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)
修改为key: "modificationDate"
顺便说一句,我找到了另一种方法:
__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。
我更新了答案以包括返回任何资产类型,以及 simpler/cleaner 返回资产的方式。
不需要比赛处理员。
func fetchLastAsset() -> PHAsset? {
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
fetchOptions.fetchLimit = 1
let fetchResult = PHAsset.fetchAssets(with: fetchOptions)
return fetchResult.firstObject
}
我有一个应用程序使用 UIImagePickerController 从相机和照片库中检索照片。 在图像选择器委托中,我只想保存所选图像的 NSURL (UIImagePickerControllerReferenceURL) 以节省内存。当用户稍后需要查看图像时,我直接从照片库使用 PHCachingImageManager 加载它。
现在 - 这整个过程对于用户从库中选择的图片非常有效,但对于相机直接拍摄的图片则效果不佳(因为没有 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)
}
}
关于如何获取已保存图片的 url 有什么想法吗?
最好的, 乔治
更新:我好像找到了这个问题的答案。
第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,而是一个不会改变的唯一标识符。这样,您就可以完美访问保存的图片了。
希望这对其他人有帮助!
我同意你的看法。
但是,如果图像的 Exif 具有更早的日期。
let fetchResult = PHAsset.fetchAssetsWithMediaType(.Image, options: fetchOptions)
fetchResult.firstObject
fetchResult.firstObject不是你刚刚保存的那个
或许你可以将fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)
修改为key: "modificationDate"
顺便说一句,我找到了另一种方法:
__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。
我更新了答案以包括返回任何资产类型,以及 simpler/cleaner 返回资产的方式。
不需要比赛处理员。
func fetchLastAsset() -> PHAsset? {
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
fetchOptions.fetchLimit = 1
let fetchResult = PHAsset.fetchAssets(with: fetchOptions)
return fetchResult.firstObject
}