如何将 PHAsset 与 UIImage 进行比较

3

我已经将一些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];

其中selectedAssets是一个PHAsset数组,image是一个UIImage对象。

因此,我已经实现了如下的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];
}

但这并没有起作用!

1个回答

8

你不应该比较图片,而应该比较PHAsset或其有用的部分localIdentifier。

用于区分资产的东西称为PHAsset的localIdentifier属性localIdentifier

苹果文档将其定义为:

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;
            });
        }];

现在您正在异步加载图片以获得平滑的用户体验,并通过仅显示需要的图像而保存内存,而不是存储所有图像。 (您可以通过引入缓存来提高性能,但这不是重点)。
最后回到您的问题,要删除某个特定图像,您只需要使用本地标识符,因为对于每个PHAsset或索引,它都是唯一的。
假设您要删除表格视图中正在显示特定图像的某些单元格。
- (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];
    }
}];

}

1
尽可能提供您需要的详细答案/示例。 - malaki1974

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接