iOS Photokit - PHAsset pixelWidth和pixelHeight与高分辨率图像

时间:2017-04-24 13:30:34

标签: ios objective-c phasset photokit phassetslibrary

我的公司通过获取PHAssets来获取正确的大小元数据存在很大问题。 我们开发了一个iOS应用程序,允许客户从库中选择图片,获取每个图片的大小(以像素为单位),计算坐标以调整我们销售的小工具,然后将高质量版本的图片上传到我们的服务器以打印小工具。 对于我们的一些客户来说,问题在于发送的一些高质量图片的像素大小与PHAsset对象给出的pixelWidth和pixelHeight不匹配。 举个例子,我们有一张图片:

    据报道,
  • 是PHAsset对象的2096x3724
  • 但是,当请求全尺寸图像时,会生成1536x2730图片

图片不在iCloud中,由运行iOS 10.2的iPhone 6 SE发送。 这是获取完整尺寸图像版本的代码:

PHImageRequestOptions *imgOpts = [[PHImageRequestOptions alloc] init];
imgOpts.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
imgOpts.networkAccessAllowed = YES;
imgOpts.resizeMode = PHImageRequestOptionsResizeModeExact;
imgOpts.version = PHImageRequestOptionsVersionCurrent;  

PHCachingImageManager *imageManager = [[PHCachingImageManager alloc] init];

[imageManager requestImageForAsset:imageAsset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:imgOpts resultHandler:^(UIImage *  result, NSDictionary *  info) {
    NSData * imageData = UIImageJPEGRepresentation(result, 0.92f);
    //UPLOAD OF imageData TO SERVER HERE
}]

还尝试使用requestImageDataForAsset方法,但没有运气:

PHImageRequestOptions *imgOpts = [[PHImageRequestOptions alloc] init];
imgOpts.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
imgOpts.networkAccessAllowed = YES;
imgOpts.resizeMode = PHImageRequestOptionsResizeModeExact;
imgOpts.version = PHImageRequestOptionsVersionCurrent;  

PHCachingImageManager *imageManager = [[PHCachingImageManager alloc] init];

[imageManager requestImageDataForAsset:imageAsset options:imgOpts resultHandler:^(NSData * imageData, NSString * dataUTI, UIImageOrientation orientation, NSDictionary *  info) {
    //UPLOAD OF imageData TO SERVER HERE
}]

在上传之前,从每张图片的高分辨率版本获取精确尺寸对我们来说不是一个选项,因为当从库中选择大量资源时,它会降低很多性能。

我们是否遗失或做错了什么? 有没有办法在没有将全分辨率图像加载到内存中的情况下获取像素的资源大小? 谢谢你的帮助

2 个答案:

答案 0 :(得分:0)

这是由于Photos框架中的错误所致。有关该错误的详细信息,请参见here

有时,在编辑照片后,会创建较小的版本。这仅适用于一些较大的照片。

调用requestImageForAsset:(使用PHImageManagerMaximumSize)或requestImageDataForAsset:(使用PHImageRequestOptionsDeliveryModeHighQualityFormat)时,尝试检索已编辑的版本时,将从较小的文件版本中读取数据( PHImageRequestOptionsVersionCurrent)。

上述方法的回调中的info将指向图像的路径。例如:
PHImageFileURLKey = "file:///[...]DCIM/100APPLE/IMG_0006/Adjustments/IMG_0006.JPG";
检查该文件夹后,我能够找到另一张图像FullSizeRender.jpg-该图像具有完整的大小并包含最新的编辑内容。因此,当存在这样的文件时,一种方法是尝试从FullSizeRender.jpg进行读取。


从iOS 9开始,还可以使用PHAssetResourceManager

以最高分辨率获取最新编辑。
// if (@available(iOS 9.0, *)) {
// check if a high quality edit is available
NSArray<PHAssetResource *> *resources = [PHAssetResource assetResourcesForAsset:_asset];
PHAssetResource *hqResource = nil;
for (PHAssetResource *res in resources) {
    if (res.type == PHAssetResourceTypeFullSizePhoto) {
        // from my tests so far, this is only present for edited photos
        hqResource = res;
        break;
    }
}

if (hqResource) {
    PHAssetResourceRequestOptions *options = [[PHAssetResourceRequestOptions alloc] init];
    options.networkAccessAllowed = YES;
    long long fileSize = [[hqResource valueForKey:@"fileSize"] longLongValue];
    NSMutableData *fullData = [[NSMutableData alloc] initWithCapacity:fileSize];

    [[PHAssetResourceManager defaultManager] requestDataForAssetResource:hqResource options:options dataReceivedHandler:^(NSData * _Nonnull data) {
        // append the data that we're receiving
        [fullData appendData:data];
    } completionHandler:^(NSError * _Nullable error) {
        // handle completion, using `fullData` or `error`
        // uti == hqResource.uniformTypeIdentifier
        // orientation == UIImageOrientationUp
    }];
}
else {
    // use `requestImageDataForAsset:`, `requestImageForAsset:` or `requestDataForAssetResource:` with a different `PHAssetResource`
}

答案 1 :(得分:-1)

你可以尝试这个来获取相机滚动图片:

__weak __typeof(self) weakSelf = self;
PHFetchResult<PHAssetCollection *> *albums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumSelfPortraits options:nil];
[albums enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull album, NSUInteger idx, BOOL * _Nonnull stop) {
    PHFetchOptions *options = [[PHFetchOptions alloc] init];
    options.wantsIncrementalChangeDetails = YES;
    options.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d",PHAssetMediaTypeImage];
    options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
    PHFetchResult<PHAsset *> *assets = [PHAsset fetchAssetsInAssetCollection:album options:options];
    if(assets.count>0)
    {
        [assets enumerateObjectsUsingBlock:^(PHAsset * _Nonnull asset, NSUInteger idx, BOOL * _Nonnull stop) {
            if(asset!=nil)
            {
                [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFill options:nil resultHandler:^(UIImage *result, NSDictionary *info)
                 {
                     dispatch_async(dispatch_get_main_queue(), ^{
                         [weakSelf addlocalNotificationForFilters:result];
                         // [weakSelf.buttonGalery setImage:result forState:UIControlStateNormal];
                     });
                 }];
                *stop = YES;
            }
            else{
                [weakSelf getlatestAferSelfie];
            }
        }];
    }