【问题标题】:How to compare PHAsset to UIImage如何将 PHAsset 与 UIImage 进行比较
【发布时间】:2016-08-08 12:25:44
【问题描述】:

我已将一些PHAsset 转换为UIImage

 PHImageManager *manager = [PHImageManager defaultManager];
            [manager requestImageForAsset:asset
                               targetSize:PHImageManagerMaximumSize
                              contentMode:PHImageContentModeDefault
                                  options:requestOptions
                            resultHandler:^void(UIImage *image, NSDictionary *info) {
                                convertedImage = image;
                                [images addObject:convertedImage];
                            }];

现在我想做这样的事情:

[selectedAssets removeObject:image];

其中selectedAssetsPHAsset 的数组,imageUIImage

所以我已经像这样实现了 isEqual:

- (BOOL)isEqual:(id)other {
    if (other == self)
        return YES;
    if (!other || ![[other class] isEqual:[self class]])
        return NO;

    NSData *data1 = UIImagePNGRepresentation(self.image);
    NSData *data2 = UIImagePNGRepresentation(((TINSelectedImage*)other).image);

    return   [data1 isEqual:data2];
}

但它不起作用!

【问题讨论】:

    标签: ios objective-c uiimage phasset


    【解决方案1】:

    您不应该比较图像,而应该比较 PHAsset 或其唯一有用的部分,名为 localIdentifier。

    您正在寻找区分资产的东西称为 PHAsset 的 localIdentifier 属性。

    Apple Docs 将其定义为:

    A unique string that persistently identifies the object. (read-only)
    

    抱歉,这个答案会有点宽泛,因为我不喜欢你的做法。

    如果我是你,我会这样做:

    首先创建一个自定义类,我们将其命名为 PhotoInfo。 (如果您对保留有关照片的大量信息不感兴趣,则实际上不必这样做。如果是这种情况,请直接使用 PHAssets 的 PFFetchResults。但是,我将使用 CustomClass)。

    在 PhotoInfo.h 中:

    #import <Foundation/Foundation.h>
    @interface PhotoInfo : NSObject
    
    @property NSString *localIdentifier;
    
    @end  
    

    现在不要使用图像数组,而是使用您创建的包含 localIdentifier 的自定义类。像这样:

    PhotoInfo *photo = [[PhotoInfo alloc] init];
    photo.localIdentifier = asset.localIdentifier;
    

    假设你想从图库中获取图片,你会这样做:

    -(PHFetchResult*) getAssetsFromLibrary
    {
        PHFetchResult *allPhotos;
        PHFetchOptions *allPhotosOptions = [[PHFetchOptions alloc] init];
        allPhotosOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]]; //Get images sorted by creation date
    
        allPhotos = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:allPhotosOptions];
    
        return allPhotos;
    }
    

    要填充您的数据源,您可以执行以下操作:

    NSMutableArray *yourPhotoDataSource = [[NSMutableArray alloc] init];
    PHFetchResult * assets = [self getAssetsFromLibrary];
     for(PHAsset *asset in assets)
            {
                PhotoInfo *photo = [PhotoInfo new];
                photo.localIndentifier = asset.localIdentifier;
                [yourPhotoDataSource addObject:photo];
    
            }
    

    现在假设您必须在某处显示这些图像,并且您需要一个实际图像,因此您将执行以下操作来获取图像:

    -(void) getImageForAsset: (PHAsset *) asset andTargetSize: (CGSize) targetSize andSuccessBlock:(void (^)(UIImage * photoObj))successBlock {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            PHImageRequestOptions *requestOptions;
    
            requestOptions = [[PHImageRequestOptions alloc] init];
            requestOptions.resizeMode   = PHImageRequestOptionsResizeModeFast;
            requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeFastFormat;
            requestOptions.synchronous = true;
            PHImageManager *manager = [PHImageManager defaultManager];
            [manager requestImageForAsset:asset
                               targetSize:targetSize
                              contentMode:PHImageContentModeDefault
                                  options:requestOptions
                            resultHandler:^void(UIImage *image, NSDictionary *info) {
                                @autoreleasepool {
    
                                    if(image!=nil){
                                        successBlock(image);
                                    }
                                }
                            }];
        });
    
    }
    

    现在假设您在 tableView 中显示这些图像,在 cellForRowAtIndexPath 中,像这样调用上述方法:

      //Show a spinner
      // Give a customizable size for image. Why load the memory with full image if you don't need to show it?
     [self getImageForAsset:asset andTargetSize:yourDesiredCGSizeOfImage andSuccessBlock:^(UIImage *photoObj) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    //Update UI of cell
                    //Hide the spinner
                    cell.thumbNail.image = photoObj;
                });
            }];
    

    现在,您可以异步加载图像,获得流畅的用户体验,同时通过仅显示需要的图像而不是存储所有图像来节省内存。 (您可以通过引入缓存来提高性能,但这不是重点)。

    最后回答您的问题,要删除某个图像,您只需要 localIdentifier,因为它对于每个 PHAsset 或索引都是唯一的。

    假设您正在删除 tableView 中的某个单元格,该单元格显示您现在要删除的特定图像。

    - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        PhotoInfo *photo = [yourPhotoDataSource objectAtIndex:indexPath.row];
        [yourPhotoDataSource removeObject:photo];
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                         withRowAnimation:UITableViewRowAnimationFade];
    
    
    }
    }
    

    如果您不使用 TableView/CollectionView 并且不知道对象的索引,您可以在数组上使用快速枚举,但您必须知道要删除的对象的 localIdentifier:

    -(void) deletePhotoWithIdentifier:(NSString *) identifierStr{
    NSMutableArray *dummyArray = [[NSMutableArray alloc] initWithArray:yourPhotoDataSource]; //created because we can't modify the array we are iterating on. Otherwise it crashes. 
    [dummyArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(PhotoInfo *p, NSUInteger index, BOOL *stop) {
        if ([p.localIndentifier isEqualToString:idenfierStr]) {
            [yourPhotoDataSource removeObjectAtIndex:index];
        }
    }];
    
    }
    

    【讨论】:

    • 您(可能)需要的详尽答案/示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    • 2013-11-20
    • 2015-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多