如何在iOS中将自定义元数据写入PNG图像 [英] How to write custom metadata to PNG images in iOS

查看:598
本文介绍了如何在iOS中将自定义元数据写入PNG图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序应该能够将自定义元数据条目写入PNG图像以导出到UIPasteboard。



通过拼凑相关主题的各个帖子,我一直在能够提供下面给出的类作为源。



使用按钮触发copyPressed方法,我能够使用JPG图像(EXIF)设置自定义元数据:

 图片[6101:907]发现jpg exif字典
图片[6101:907]检查剪贴板上的图像元数据
Image [6101:907] {
ColorModel = RGB;
深度= 8;
Orientation = 1;
PixelHeight = 224;
PixelWidth = 240;
{Exif}= {
ColorSpace = 1;
PixelXDimension = 240;
PixelYDimension = 224;
UserComment =这是评论;
};
{JFIF}= {
DensityUnit = 0;
JFIFVersion =(
1,
1
);
XDensity = 1;
YDensity = 1;
};
{TIFF}= {
Orientation = 1;
};
}

虽然我能够很好地阅读PNG元数据,但我可以'好像写信给它:

 图片[6116:907]发现png属性字典
图片[6116:907检查剪贴板上的图像元数据
Image [6116:907] {
ColorModel = RGB;
深度= 8;
PixelHeight = 224;
PixelWidth = 240;
{PNG}= {
InterlaceType = 0;
};
}

然而,文档中没有任何内容表明这应该失败并且存在许多< a href =http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CGImageProperties_Reference/Reference/reference.html\"rel =nofollow noreferrer> PNG特定的元数据常量建议它应该成功。



我的应用程序应该使用PNG来避免。但似乎 ImageIO 无法与XMP一起使用。

也许您可以尝试使用 ImageMagic libexif



有用链接:

PNG规范

在iPhone上读/写图像XMP / Objective-c

PNG是否支持像作者,相机模型等元数据字段?

PNG是否包含像JPG这样的EXIF数据?

libexif .sourceforge.net


My application should be able to write custom metadata entries to PNG images for export to the UIPasteboard.

By piecing together various posts on the subject, I've been able to come up with the class given below as source.

Triggering the copyPressed method with a button, I'm able to set custom metadata with JPG images (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;
    };
}

Although I'm able to read the PNG metadata just fine, I can't seem to write to it:

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;
    };
}

However, nothing in the documentation suggests this should fail and the presence of many PNG-specific metadata constants suggests it should succeed.

My application should use PNG to avoid JPG's lossy compression.

Why can I not set custom metadata on an in-memory PNG image in iOS?

Note: I've seen this SO question, but it doesn't address the problem here, which is how to write metadata to PNG images specifically.

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

解决方案

If you will try to save your image with modified metadata

[data writeToFile:[NSTemporaryDirectory() stringByAppendingPathComponent:@"test.png"]   
       atomically:YES];

And than view it properties in Finder. You will see that kCGImagePropertyPNGDescription field was setted up successfully.

But if you will try read metadata of this new file, kCGImagePropertyPNGDescription will be lost.

ColorModel = RGB;
Depth = 8;
PixelHeight = 1136;
PixelWidth = 640;
"{PNG}" =     {
    InterlaceType = 0;
};

After some research I found that PNG doesn't contain metadata. But it may contain XMP metadata. However seems like ImageIO didn't work with XMP.
Maybe you can try to use ImageMagic or libexif.

Useful links:
PNG Specification
Reading/Writing image XMP on iPhone / Objective-c
Does PNG support metadata fields like Author, Camera Model, etc?
Does PNG contain EXIF data like JPG?
libexif.sourceforge.net

这篇关于如何在iOS中将自定义元数据写入PNG图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆