Ios 如何覆盖图像元数据?

Ios 如何覆盖图像元数据?,ios,objective-c,cocoa,metadata,Ios,Objective C,Cocoa,Metadata,如果使用CGImageDestination的原始图像元数据中已经存在key/val,则我似乎无法将图像元数据正确写入图像。如果在原始元数据中不存在key/val,则可以正常工作 就好像原始图像中的图像元数据属性优先于修改。这是我不知道的某种拜占庭式格式问题,我需要以某种不寻常的方式填充key/val,是一个bug,还是?还有人看到这个吗 下面的代码和输出,适用于它正常工作(如果尚未设置值)和写入失败(如果已将值设置为其他值)的两种情况 非常感谢您的帮助 以下是我创建图像数据的位置/方式: //

如果使用CGImageDestination的原始图像元数据中已经存在key/val,则我似乎无法将图像元数据正确写入图像。如果在原始元数据中不存在key/val,则可以正常工作

就好像原始图像中的图像元数据属性优先于修改。这是我不知道的某种拜占庭式格式问题,我需要以某种不寻常的方式填充key/val,是一个bug,还是?还有人看到这个吗

下面的代码和输出,适用于它正常工作(如果尚未设置值)和写入失败(如果已将值设置为其他值)的两种情况

非常感谢您的帮助

以下是我创建图像数据的位置/方式:

// 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;
}
以下是映像具有密钥现有值时的NSLogs:

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...>
}
------------------------------
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...>
}
------------------------------
之前:
------------------------------{
“{IPTC}”={
“标题/摘要”=模糊;
创建日期=20130923;
DigitalCreationDate=20130923;
DigitalCreationTime=173815;
关键词=(
伪造的
);
补充分类=(
伪造的
);
创建的时间=173815;
};
}
------------------------------
参数:
------------------------------{
“{IPTC}”={
“标题/摘要”=“硬编码标题”;
创建日期=20130923;
DigitalCreationDate=20130923;
DigitalCreationTime=173815;
关键词=(
伪造的
);
补充分类=(
伪造的
);
创建的时间=173815;
};
}
------------------------------
之后:
------------------------------{
“{IPTC}”={
“标题/摘要”=模糊;
创建日期=20130923;
DigitalCreationDate=20130923;
DigitalCreationTime=173815;
关键词=(
伪造的
);
补充分类=(
伪造的
);
创建的时间=173815;
};
}
------------------------------
以下是映像没有密钥值时的NSLogs:

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...>
}
------------------------------
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...>
}
------------------------------
之前:
------------------------------{
“{IPTC}”={
创建日期=20130925;
DigitalCreationDate=20130925;
DigitalCreationTime=192856;
关键词=(
伪造的
);
补充分类=(
伪造的
);
创建时间=192856;
};
}
------------------------------
参数:
------------------------------{
“{IPTC}”={
“标题/摘要”=“硬编码标题”;
创建日期=20130925;
DigitalCreationDate=20130925;
DigitalCreationTime=192856;
关键词=(
伪造的
);
补充分类=(
伪造的
);
创建时间=192856;
};
}
------------------------------
之后:
------------------------------{
“{IPTC}”={
“标题/摘要”=“硬编码标题”;
创建日期=20130925;
DigitalCreationDate=20130925;
DigitalCreationTime=192856;
关键词=(
伪造的
);
补充分类=(
伪造的
);
创建时间=192856;
};
}
------------------------------

根据IPTC文档,描述字段绑定到TIFF和EXIF地址。更改TIFF中的值也会更新IPTC条目!
感谢用户2452250提供的提示。

我也尝试了CGImageDestinationCopyImageSource,但如果您多次编辑同一文件,则会损坏JPEG数据流。苹果技术支持事件开始…你好,斯科特!有什么消息吗?我也有同样的问题!请让我知道!看看这篇文章:Image/IO在元数据方面很弱。我建议您使用Adobe的XMP工具包。您可以将XMP数据读/写为所有媒体格式,如图像、视频、pdf等。我试图在这里解释。好的,伙计们!我找到了解决办法!根据IPTC文档,描述字段绑定到TIFF和EXIF地址。更改TIFF中的值也会更新IPTC条目!既然我不能给自己投票权,如果莫哈奇可以把这个作为答案,我可以给+50而不是扔掉它!:)伟大的可以在大约一小时内分配50个!谢谢你的帮助,感谢你迟来的赏金!忘了。。给你。。及时D@mohacs-我遵循了问题中的代码,并且看起来原始图像中的图像元数据属性优先于修改。我试图应用用户2452250的答案,但可能我还不够理解。如果你想了解我的观点,我确实有一个问题:某个白痴拥有比智力更大的权威,并将其标记为另一个问题的复制品。如果有什么的话,那就是这个的复制品。你能帮忙吗?@Lucy,关于你的问题:增加DPI并不会使图像变大。DPI用于确定打印图像的大小。无任何内容。@mohacs-让我们假设我不希望图像变大。让我们假设我所要做的就是将dpi从72更改为500。有办法吗?