在 iOS8 上使用 UIImagePicker 结果 URL 和 PHAsset 从“我的照片流”加载图像
Posted
技术标签:
【中文标题】在 iOS8 上使用 UIImagePicker 结果 URL 和 PHAsset 从“我的照片流”加载图像【英文标题】:Loading image from "My Photo Stream" using UIImagePicker results URL and PHAsset on iOS8 【发布时间】:2014-10-27 13:20:08 【问题描述】:我将一个应用程序从 ios7 更新到 ios8,并且努力让 UIImagePicker 工作以从“我的照片流”类别的照片中加载图片。 UIImagePicker 实现是标准的,我使用以下命令检索所选照片的 URL:
NSURL *url = [info objectForKey:@"UIImagePickerControllerReferenceURL"];
然后我使用新的 IOS8 API 来加载这张照片:
PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[url] options:nil];
这不起作用。 result.count 为零,没有找到图像。 URL 的 UUID 与我从“时刻”或“相机胶卷”中选择照片的 UUID 不同,但看起来格式正确。 (手机运行的是 8.1):
url NSURL * @"assets-library://asset/asset.JPG?id=4522DBD1-862C-42BE-AF7C-0D6C76CA7590&ext=JPG"
有人有一些代码可以从“我的照片流”中加载照片,或者有办法为 UIImagePicker 显示禁用它吗?
使用旧的 ALAssetsLibraryassetForURL API 也无法加载这些图像。
【问题讨论】:
url是以assets-library开头的,所以应该使用ALAssetsLibrary来获取。 就像我说的......“使用旧的 ALAssetsLibraryassetForURL API 也无法加载这些图像。” Apple 的 fetchAssetsWithALAssetURLs 文档称该 URL 是“之前从 ALAsset 对象中检索到的每个资产 URL。” 所以问题是“如何从我的照片流中加载照片? 当然,或者如何在 iOS8 上打开一个图像选择器,显示所有可用的照片以及如何加载每种类型。 '我的照片流'发生了一些奇怪的事情。 你有没有想过这个问题? 【参考方案1】:我想你可以试试这个来获取“我的照片流”相册。
PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumMyPhotoStream options:nil];
My Photo Stream 相册中的照片上传到 iCloud,iCloud 会高效管理它们,30 天内拍摄的照片在那里,我认为 PHAsset 或 ALAssetLibrary 处理本地存储的资产。这是我在我的设备上做的一个测试,我使用 imagePicker 从流相册中获取照片 url,这是
"assets-library://asset/asset.JPG?id=60AE4E50-B835-47EB-B896-5974C21F8C9B&ext=JPG";
在同一张照片上使用 PHAsset 我得到了它的 localIdentifier:
"60AE4E50-B835-47EB-B896-5974C21F8C9B/L0/001"
所以我认为您可以从 url 中删除 id,并找出哪个资产的本地标识符包含它,然后您就可以获得所需的 PHAsset。
【讨论】:
谢谢。这确实允许您遍历 PHAssetCollection 并从“我的照片流”中获取照片列表,但每个 PHAsset 中没有 URL 与 UIImagePicker 为“我的照片流”中所选照片返回的内容相匹配。 iOS8 中有 UIImagePicker 的替代品吗? 当您使用 UIImagePicker 时,我的照片流应该显示为相册,UIImagePicker 适用于 iOS 8,您可以使用集合视图来显示获取的图像。我建议你看看 Apple 的 Photos 示例。 Apple 的照片示例根本不使用 UIImagePicker。我遇到的问题是 UIImagePicker (显示“我的照片流”列表)允许选择这种类型的照片,但它返回的 URL 对实际加载该文件无用。新旧 API 都不起作用。这些是我设备上的本地照片,所以图像并不只是在云端。 [info objectForkey:@"UIImagePickerControllerOriginalImage"] 会给你你想要的 UIImage,你需要 url 做什么?【参考方案2】:在任何地方都没有找到任何答案后,我为 PHAsset 创建了以下扩展,它在 iOS 8.2 中运行良好,尽管我认为它在理论上很慢。尽管之前的一位 cmets 说这已在 iOS8.2 测试版中修复,但现在 iOS8.2 发布后,我仍然存在该错误。
import Photos
import UIKit
extension PHAsset
class func fetchAssetWithALAssetURL (alURL: NSURL) -> PHAsset?
let phphotoLibrary = PHPhotoLibrary.sharedPhotoLibrary()
let assetManager = PHImageManager()
var phAsset : PHAsset?
let optionsForFetch = PHFetchOptions()
optionsForFetch.includeHiddenAssets = true
var fetchResult = PHAsset.fetchAssetsWithALAssetURLs([alURL], options: optionsForFetch)
if fetchResult?.count > 0
return fetchResult[0] as? PHAsset
else
var str = alURL.absoluteString!
let startOfString = advance(find(str, "=")!, 1)
let endOfString = advance(startOfString, 36)
let range = Range<String.Index>(start:startOfString, end:endOfString)
let localIDFragment = str.substringWithRange(range)
let fetchResultForPhotostream = PHAssetCollection.fetchAssetCollectionsWithType(PHAssetCollectionType.Album, subtype: PHAssetCollectionSubtype.AlbumMyPhotoStream, options: nil)
if fetchResultForPhotostream?.count > 0
let photostream = fetchResultForPhotostream![0] as PHAssetCollection
let fetchResultForPhotostreamAssets = PHAsset.fetchAssetsInAssetCollection(photostream, options: optionsForFetch)
if fetchResultForPhotostreamAssets?.count >= 0
var stop : Bool = false
for var i = 0; i < fetchResultForPhotostreamAssets.count && !stop; i++
let phAssetBeingCompared = fetchResultForPhotostreamAssets[i] as PHAsset
if phAssetBeingCompared.localIdentifier.rangeOfString(localIDFragment, options: nil, range: nil, locale: nil) != nil
phAsset = phAssetBeingCompared
stop = true
return phAsset
return nil
【讨论】:
【参考方案3】:此处讨论了使用 ALAssetsLibrary 从“我的照片流”中加载具有指定 URL 的图像:
ALAssetsLibrary assetForURL: always returning nil for photos in "My Photo Stream" in iOS 8.1
简而言之,您必须遍历照片流中的所有项目并将它们的 URL 与您的 URL 进行比较,而不是使用assetForURL。上面的链接包含一个代码示例。
看起来很别扭,工作比assetForURL慢,并且确定是否没有找到具有指定URL的任何文件并不是那么容易,但我没有找到任何其他方法(迁移到Photos框架除外) .
【讨论】:
【参考方案4】:对于 PHAsset,我使用
[[PHImageManager defaultManager] requestImageForAsset:imageAsset
targetSize:targetSize
contentMode:PHImageContentModeAspectFit
options:options
resultHandler:^(UIImage *img, NSDictionary *info)
// code for handle image ];
我尝试使用 requestImageDataForAsset
,但对于流式传输的照片,它返回 nil。
【讨论】:
【参考方案5】:在 8.0 中为我工作
import Photos
func imageFromAsset(nsurl: NSURL)
let asset = PHAsset.fetchAssetsWithALAssetURLs([nsurl], options: nil).firstObject as! PHAsset
let targetSize = CGSizeMake(300, 300)
var options = PHImageRequestOptions()
PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: targetSize, contentMode: PHImageContentMode.AspectFit, options: options, resultHandler:
(result, info) in
// imageE - UIImageView on scene
self.imageE.image = result
)
【讨论】:
@Opticon 想发表以下评论: - 无法发表评论,所以我这样问。我实现了这个,但它总是返回一个 60x60 aprox。图像,无论我在 targetSize 中设置什么。你知道我怎样才能恢复原始照片吗?谢谢以上是关于在 iOS8 上使用 UIImagePicker 结果 URL 和 PHAsset 从“我的照片流”加载图像的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iOS 上的 UIImagePicker 中获取实际图像框架的大小?
如何在 iOS 的某些文件输入字段上获取 UIWebView 中 UIImagePicker 选择的图像?