如果使用CGImageDestination在原始图像元数据中已经存在key / val,我似乎无法正确地将图像元数据写入图像。如果原始元数据中没有key / val,它就可以正常工作。
几乎就像原始图像中的图像元数据属性优先于修改一样。这是我不知道的某种拜占庭格式问题,我需要以某种不寻常的方式填充键/ val,一个bug,还是?其他人看过这个吗?
下面的代码和输出,对于它正常工作的两种情况(如果值尚未设置)并且无法写入(如果该值已经设置为其他值)。
非常感谢任何帮助。
以下是创建图像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...>
}
------------------------------
答案 0 :(得分:3)
根据IPTC文档,描述字段绑定到TIFF和EXIF地址。更改TIFF中的值也会更新IPTC条目! 谢谢user2452250的提示。