Interpréter les métadonnées XMP dans ALAssetRepresentation

95

Lorsqu'un utilisateur apporte des modifications (recadrage, suppression des yeux rouges, ...) aux photos dans l'application Photos.app intégrée sur iOS, les modifications ne sont pas appliquées au fichierfullResolutionImage renvoyé par le correspondant ALAssetRepresentation.

Toutefois, les modifications sont appliquées au thumbnailet au fullScreenImagerenvoyé par le ALAssetRepresentation. De plus, des informations sur les modifications appliquées peuvent être trouvées dans le ALAssetRepresentationdictionnaire de métadonnées du via la touche @"AdjustmentXMP".

Je voudrais appliquer ces changements au fullResolutionImagemoi - même pour préserver la cohérence. J'ai découvert que sur iOS6 + CIFilter , filterArrayFromSerializedXMP: inputImageExtent:error:on peut convertir ces métadonnées XMP en un tableau de CIFilter:

ALAssetRepresentation *rep; 
NSString *xmpString = rep.metadata[@"AdjustmentXMP"];
NSData *xmpData = [xmpString dataUsingEncoding:NSUTF8StringEncoding];

CIImage *image = [CIImage imageWithCGImage:rep.fullResolutionImage];

NSError *error = nil;
NSArray *filterArray = [CIFilter filterArrayFromSerializedXMP:xmpData 
                                             inputImageExtent:image.extent 
                                                        error:&error];
if (error) {
     NSLog(@"Error during CIFilter creation: %@", [error localizedDescription]);
}

CIContext *context = [CIContext contextWithOptions:nil];

for (CIFilter *filter in filterArray) {
     [filter setValue:image forKey:kCIInputImageKey];
     image = [filter outputImage];
}

Cependant, cela ne fonctionne que pour certains filtres (rognage, amélioration automatique) mais pas pour d'autres comme la suppression des yeux rouges. Dans ces cas, les CIFilters n'ont aucun effet visible. Par conséquent, mes questions:

  • Quelqu'un a-t-il connaissance d'un moyen de supprimer les yeux rouges CIFilter? (D'une manière cohérente avec l'application Photos.app. Le filtre avec la clé kCIImageAutoAdjustRedEyene suffit pas. Par exemple, il ne prend pas de paramètres pour la position des yeux.)
  • Existe-t-il une possibilité de générer et d'appliquer ces filtres sous iOS 5?
andreas
la source
Ce lien est vers une autre question Stackoverflow qui fournit un algorithme pour les yeux rouges. Ce n'est pas beaucoup mais c'est un début. stackoverflow.com/questions/133675/red-eye-reduction-algorithm
Roecrew
Sur iOS 7, le code répertorié applique correctement le filtre de suppression des yeux rouges (filtre interne CIRedEyeCorrections).
paiv

Réponses:

2
ALAssetRepresentation* representation = [[self assetAtIndex:index] defaultRepresentation];

// Create a buffer to hold the data for the asset's image
uint8_t *buffer = (Byte*)malloc(representation.size); // Copy the data from the asset into the buffer
NSUInteger length = [representation getBytes:buffer fromOffset: 0.0  length:representation.size error:nil];

if (length==0)
    return nil;

// Convert the buffer into a NSData object, and free the buffer after.

NSData *adata = [[NSData alloc] initWithBytesNoCopy:buffer length:representation.size freeWhenDone:YES];

// Set up a dictionary with a UTI hint. The UTI hint identifies the type
// of image we are dealing with (that is, a jpeg, png, or a possible
// RAW file).

// Specify the source hint.

NSDictionary* sourceOptionsDict = [NSDictionary dictionaryWithObjectsAndKeys:

(id)[representation UTI], kCGImageSourceTypeIdentifierHint, nil];

// Create a CGImageSource with the NSData. A image source can
// contain x number of thumbnails and full images.

CGImageSourceRef sourceRef = CGImageSourceCreateWithData((CFDataRef) adata,  (CFDictionaryRef) sourceOptionsDict);

[adata release];

CFDictionaryRef imagePropertiesDictionary;

// Get a copy of the image properties from the CGImageSourceRef.

imagePropertiesDictionary = CGImageSourceCopyPropertiesAtIndex(sourceRef,0, NULL);

CFNumberRef imageWidth = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyPixelWidth);

CFNumberRef imageHeight = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyPixelHeight);

int w = 0;

int h = 0;

CFNumberGetValue(imageWidth, kCFNumberIntType, &w);

CFNumberGetValue(imageHeight, kCFNumberIntType, &h);

// Clean up memory

CFRelease(imagePropertiesDictionary);
Yash Golwara
la source