/ / Wie man PHAsset mit UIImage vergleicht - ios, objective-c, uiimage, phasset

Wie man PHAsset mit UIImage vergleicht - ios, objective-c, uiimage, phasset

Ich habe einige konvertiert PHAsset zu 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];
}];

Jetzt möchte ich so etwas machen:

[selectedAssets removeObject:image];

woher selectedAssets ist eine Reihe von PHAsset und image ist ein UIImage

also habe ich das isEqual wie folgt implementiert:

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

Aber es funktioniert nicht !

Antworten:

6 für die Antwort № 1

Sie sollten keine Bilder vergleichen, sondern PHAssets oder deren einzigen nützlichen Teil namens localIdentifier.

Was Sie suchen, um zwischen den Assets zu unterscheiden, wird aufgerufen localIdentifier Eigenschaft von PHAsset.

Die Apple Docs definieren es als:

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

Tut mir leid, diese Antwort wird ein bisschen breit sein, weil ich deine Herangehensweise hier nicht mag.

Wenn ich du wäre, würde ich es so machen:

Erstellen Sie zunächst eine benutzerdefinierte Klasse, nennen Sie sieFotoinfo. (Sie müssen das nicht wirklich tun, wenn Sie nicht daran interessiert sind, viele Informationen über Ihre Fotos zu speichern. Wenn dies der Fall ist, verwenden Sie die PFFetchResults von PHAssets direkt, wenn Sie möchten. Ich werde jedoch mit CustomClass gehen) .

in Photoinfo.h:

#import <Foundation/Foundation.h>
@interface PhotoInfo : NSObject

@property NSString *localIdentifier;

@end

Verwenden Sie jetzt anstelle einer Reihe von Bildern diese benutzerdefinierte Klasse, die localIdentifier enthalten wird. So was:

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

Sagen wir, Sie möchten Bilder aus der Galerie holen, dann würden Sie so etwas tun:

-(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;
}

Um Ihre dataSource zu füllen, tun Sie etwas wie:

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

}

Jetzt sagen wir mal, du musst diese Bilder irgendwo anzeigen und du brauchst ein aktuelles Bild dafür, also wirst du so etwas machen um das Bild zu bekommen:

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

}

Wenn Sie nun sagen, dass Sie diese Bilder in einer tabellarischen Ansicht anzeigen, rufen Sie in Ihrem cellForRowAtIndexPath die oben genannte Methode wie folgt auf:

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

Jetzt laden Sie Bilder asynchron mitBenutzerfreundlichkeit Erleben und speichern Sie den Speicher, indem Sie nur die benötigten Bilder anzeigen, anstatt alle zu speichern. (Sie können die Leistung durch Einführung von Caching noch verbessern, aber das ist nicht der Punkt hier).

Endlich zu deiner Frage kommenUm ein bestimmtes Bild zu entfernen, benötigen Sie nur den localIdentifier, da dieser für jedes PHAsset oder jeden Index eindeutig ist.

Angenommen, Sie löschen eine Zelle in Ihrer tableView, die das bestimmte Bild zeigt, das Sie jetzt entfernen möchten.

- (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];


}
}

Wenn Sie kein TableView / CollectionView verwendenund Sie kennen den Index des Objekts nicht, Sie können eine schnelle Enumeration für Ihr Array verwenden, aber dann müssen Sie den localIdentifier des Objekts kennen, das Sie löschen möchten:

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

}