Ric*_*aca 12 png metadata objective-c uipasteboard ios
我的应用程序应该能够将自定义元数据条目写入PNG图像以导出到UIPasteboard.
通过拼凑关于这个主题的各种帖子,我已经能够提出下面给出的课程作为来源.
使用按钮触发copyPressed方法,我可以使用JPG图像(EXIF)设置自定义元数据:
Image[6101:907] found jpg exif dictionary
Image[6101:907] checking image metadata on clipboard
Image[6101:907] {
    ColorModel = RGB;
    Depth = 8;
    Orientation = 1;
    PixelHeight = 224;
    PixelWidth = 240;
    "{Exif}" =     {
        ColorSpace = 1;
        PixelXDimension = 240;
        PixelYDimension = 224;
        UserComment = "Here is a comment";
    };
    "{JFIF}" =     {
        DensityUnit = 0;
        JFIFVersion =         (
            1,
            1
        );
        XDensity = 1;
        YDensity = 1;
    };
    "{TIFF}" =     {
        Orientation = 1;
    };
}
虽然我能够很好地阅读PNG元数据,但我似乎无法写入:
Image[6116:907] found png property dictionary
Image[6116:907] checking image metadata on clipboard
Image[6116:907] {
    ColorModel = RGB;
    Depth = 8;
    PixelHeight = 224;
    PixelWidth = 240;
    "{PNG}" =     {
        InterlaceType = 0;
    };
}
但是,文档中没有任何内容表明这应该失败,并且存在许多特定于PNG的元数据常量表明它应该成功.
我的应用程序应该使用PNG来避免JPG的有损压缩.
为什么我不能在iOS中的内存中PNG图像上设置自定义元数据?
注意:我已经看到了这个问题,但它没有解决这里的问题,即如何专门为PNG图像写入元数据.
IMViewController.m
#import "IMViewController.h"
#import <ImageIO/ImageIO.h>
@interface IMViewController ()
@end
@implementation IMViewController
- (IBAction)copyPressed:(id)sender
{
//    [self copyJPG];
    [self copyPNG];
}
-(void)copyPNG
{
    NSData *pngData = UIImagePNGRepresentation([UIImage imageNamed:@"wow.png"]);
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)pngData, NULL);
    NSDictionary *metadata = (__bridge NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
    NSMutableDictionary *mutableMetadata = [metadata mutableCopy];
    NSMutableDictionary *dict = [[mutableMetadata objectForKey:(NSString *) kCGImagePropertyPNGDictionary] mutableCopy];
    if (dict) {
        NSLog(@"found png property dictionary");
    } else {
        NSLog(@"creating png property dictionary");
        dict = [NSMutableDictionary dictionary];
    }
    // set values on the root dictionary
    [mutableMetadata setObject:@"Name of Software" forKey:(NSString *)kCGImagePropertyPNGDescription];
    [mutableMetadata setObject:dict forKey:(NSString *)kCGImagePropertyPNGDictionary];
    // set values on the internal dictionary
    [dict setObject:@"works" forKey:(NSString *)kCGImagePropertyPNGDescription];
    CFStringRef UTI = CGImageSourceGetType(source);
    NSMutableData *data = [NSMutableData data];
    CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef) data, UTI, 1, NULL);
    if (!destination) {
        NSLog(@">>> Could not create image destination <<<");
        return;
    }
    CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef) mutableMetadata);
    BOOL success = CGImageDestinationFinalize(destination);
    if (!success) {
        NSLog(@">>> Error Writing Data <<<");
    }
    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
    [pasteboard setData:data forPasteboardType:@"public.png"];
    [self showPNGMetadata];
}
-(void)copyJPG
{
    NSData *jpgData = UIImageJPEGRepresentation([UIImage imageNamed:@"wow.jpg"], 1);
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) jpgData, NULL);
    NSDictionary *metadata = (__bridge NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
    NSMutableDictionary *mutableMetadata = [metadata mutableCopy];
    NSMutableDictionary *exif = [[mutableMetadata objectForKey:(NSString *)kCGImagePropertyExifDictionary] mutableCopy];
    if (exif) {
        NSLog(@"found jpg exif dictionary");
    } else {
        NSLog(@"creating jpg exif dictionary");
    }
    // set values on the exif dictionary
    [exif setObject:@"Here is a comment" forKey:(NSString *)kCGImagePropertyExifUserComment];
    [mutableMetadata setObject:exif forKey:(NSString *)kCGImagePropertyExifDictionary];
    CFStringRef UTI = CGImageSourceGetType(source);
    NSMutableData *data = [NSMutableData data];
    CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef) data, UTI, 1, NULL);
    if(!destination) {
        NSLog(@">>> Could not create image destination <<<");
        return;
    }
    CGImageDestinationAddImageFromSource(destination,source, 0, (__bridge CFDictionaryRef) mutableMetadata);
    BOOL success = CGImageDestinationFinalize(destination);
    if (!success) {
        NSLog(@">>> Could not create data from image destination <<<");
    }
    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
    [pasteboard setData:data forPasteboardType:@"public.jpeg"];
    [self showJPGMetadata];
}
-(void)showJPGMetadata
{
    NSLog(@"checking image metadata on clipboard");
    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
    NSData *data = [pasteboard dataForPasteboardType:@"public.jpeg"];
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    NSDictionary *metadata = (__bridge NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source,0,NULL);
    NSLog(@"%@", metadata);
}
-(void)showPNGMetadata
{
    NSLog(@"checking image metadata on clipboard");
    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
    NSData *data = [pasteboard dataForPasteboardType:@"public.png"];
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    NSDictionary *metadata = (__bridge NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source,0,NULL);
    NSLog(@"%@", metadata);
}
@end
如果您尝试使用修改后的元数据保存图像
[data writeToFile:[NSTemporaryDirectory() stringByAppendingPathComponent:@"test.png"]   
       atomically:YES];
然后在 Finder 中查看它的属性。您将看到该kCGImagePropertyPNGDescription字段已成功设置。  

但如果您尝试读取这个新文件的元数据,kCGImagePropertyPNGDescription将会丢失。
ColorModel = RGB;
Depth = 8;
PixelHeight = 1136;
PixelWidth = 640;
"{PNG}" =     {
    InterlaceType = 0;
};
经过一些研究,我发现 PNG 不包含元数据。但它可能包含XMP 元数据。但似乎ImageIO不适用于 XMP。
也许您可以尝试使用ImageMagic或libexif。
有用的链接:
PNG 规范
在 iPhone / Objective-c 上读取/写入图像 XMP 
PNG 是否支持作者、相机型号等元数据字段?
PNG 是否像 JPG 一样包含 EXIF 数据?
libexif.sourceforge.net
| 归档时间: | 
 | 
| 查看次数: | 4920 次 | 
| 最近记录: |