如果 CGImageDestination 的原始图像元数据中已经存在密钥/值,我似乎无法将图像元数据正确写入图像。如果原始元数据中不存在它们的键/值,它就可以正常工作。
就好像原始图像中的图像元数据属性优先于修改一样。这是我不知道的某种拜占庭格式问题,我需要以某种不寻常的方式填充键/值,是错误还是?还有人看到这个吗?
下面的代码和输出,适用于正常工作(如果尚未设置该值)和无法写入(如果该值已设置为其他值)的两种情况。
非常感谢任何帮助。
这是我创建图像 NSData 的位置/方式:
// convert the existing asset to nsdata to overwrite itself
ALAssetRepresentation* rep = [asset defaultRepresentation];
Byte* buffer = (Byte*)malloc(rep.size);
NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
NSData* imageData = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
// write the metadata directly into the nsdata of the image itself
NSData* newImage = [self writeMetadataIntoImageData:imageData metadata:newMetadata];
这是元数据的实际修改:
- (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 (e.g., 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;
}
以下是当图像具有键的现有值时的 NSLog:
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...>
}
------------------------------
以下是图像没有键值时的 NSLog:
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...>
}
------------------------------