¿Cómo sobreescribe los metadatos de las imágenes?

Parece que no puedo escribir los metadatos de la image en la image correctamente si la key / val ya está presente en los metadatos originales de la image con CGImageDestination. Funciona bien si no están presentes key / val en los metadatos originales.

Es casi como si las properties de metadatos de image en la image original tuvieran prioridad sobre las modificaciones. ¿Es este un tipo de problema de formatting bizantino del que no tengo conocimiento, donde necesito completar la key / val de alguna manera inusual, un error o? ¿Alguien más ha visto esto?

Código y salida a continuación, para ambos casos donde funciona correctamente (si el valor aún no está establecido) y falla en la escritura (si el valor ya está establecido en otra cosa).

Cualquier ayuda apreciada muy apreciada.

Aquí es donde / cómo creo la image NSData:

// convert the existing asset to nsdata to overwrite itself ALAssetRepresentation* rep = [asset defaultRepresentation]; Byte* buffer = (Byte*)malloc(rep.size); NSUInteger buffenetworking = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil]; NSData* imageData = [NSData dataWithBytesNoCopy:buffer length:buffenetworking freeWhenDone:YES]; // write the metadata directly into the nsdata of the image itself NSData* newImage = [self writeMetadataIntoImageData:imageData metadata:newMetadata]; 

Aquí está la modificación real de los metadatos:

 - (NSData*)writeMetadataIntoImageData:(NSData*)imageData metadata:(NSMutableDictionary*)metadataAsMutable { // create an imagesourceref CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) imageData, NULL); // read and log pre write metadata NSDictionary* metadata = (NSDictionary *) CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(source,0,NULL)); NSLog(@"Before:\n------------------------------%@\n------------------------------", metadata); // set the new metadata keys here NSMutableDictionary* iptc = [metadataAsMutable[(NSString*)kCGImagePropertyIPTCDictionary] mutableCopy]; if (!iptc) { iptc = [NSMutableDictionary dictionaryWithCapacity:1]; } iptc[(NSString*)kCGImagePropertyIPTCCaptionAbstract] = @"Hardcoded Caption"; metadataAsMutable[(NSString*)kCGImagePropertyIPTCDictionary] = iptc; // log the new metadata as we want it written NSLog(@"Parameter:\n------------------------------%@\n------------------------------", metadataAsMutable); // this is the type of image (eg, public.jpeg) CFStringRef UTI = CGImageSourceGetType(source); // create a new data object and write the new image into it NSMutableData *dest_data = [NSMutableData data]; CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)dest_data,UTI,1,NULL); if(!destination) { NSLog(@"Error: Could not create image destination"); } // add the image contained in the image source to the destination, overidding the old metadata with our modified metadata CGImageDestinationAddImageFromSource(destination,source,0, (__bridge CFDictionaryRef) metadataAsMutable); BOOL success = NO; success = CGImageDestinationFinalize(destination); if(!success) { NSLog(@"Error: Could not create data from image destination"); } // read and log post write metadata CGImageSourceRef source2; source2 = CGImageSourceCreateWithData((__bridge CFDataRef) dest_data, NULL); NSDictionary *metadata2 = (NSDictionary *) CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(source2,0,NULL)); NSLog(@"After:\n------------------------------%@\n------------------------------", metadata2); // cleanup CFRelease(destination); // return the new data return dest_data; } 

Aquí están los NSLogs para cuando la image tiene un valor existente para la key:

 Before: ------------------------------{ <...snip...> "{IPTC}" = { "Caption/Abstract" = Blurry; DateCreated = 20130923; DigitalCreationDate = 20130923; DigitalCreationTime = 173815; Keywords = ( fake ); SupplementalCategory = ( fake ); TimeCreated = 173815; }; <...snip...> } ------------------------------ Parameter: ------------------------------{ <...snip...> "{IPTC}" = { "Caption/Abstract" = "Hardcoded Caption"; DateCreated = 20130923; DigitalCreationDate = 20130923; DigitalCreationTime = 173815; Keywords = ( fake ); SupplementalCategory = ( fake ); TimeCreated = 173815; }; <...snip...> } ------------------------------ After: ------------------------------{ <...snip...> "{IPTC}" = { "Caption/Abstract" = Blurry; DateCreated = 20130923; DigitalCreationDate = 20130923; DigitalCreationTime = 173815; Keywords = ( fake ); SupplementalCategory = ( fake ); TimeCreated = 173815; }; <...snip...> } ------------------------------ 

Aquí están los NSLogs para cuando la image no tiene valor para la key:

 Before: ------------------------------{ <...snip...> "{IPTC}" = { DateCreated = 20130925; DigitalCreationDate = 20130925; DigitalCreationTime = 192856; Keywords = ( fake ); SupplementalCategory = ( fake ); TimeCreated = 192856; }; <...snip...> } ------------------------------ Parameter: ------------------------------{ <...snip...> "{IPTC}" = { "Caption/Abstract" = "Hardcoded Caption"; DateCreated = 20130925; DigitalCreationDate = 20130925; DigitalCreationTime = 192856; Keywords = ( fake ); SupplementalCategory = ( fake ); TimeCreated = 192856; }; <...snip...> } ------------------------------ After: ------------------------------{ <...snip...> "{IPTC}" = { "Caption/Abstract" = "Hardcoded Caption"; DateCreated = 20130925; DigitalCreationDate = 20130925; DigitalCreationTime = 192856; Keywords = ( fake ); SupplementalCategory = ( fake ); TimeCreated = 192856; }; <...snip...> } ------------------------------ 

De acuerdo con la documentation de IPTC, el campo de descripción está vinculado a la dirección TIFF y EXIF. cambiando el valor en el TIFF, también actualiza la input IPTC. gracias user2452250 por la propina.