gpt4 book ai didi

ios - 如何在 iOS 中将自定义元数据写入 PNG 图像

转载 作者:技术小花猫 更新时间:2023-10-29 10:39:17 26 4
gpt4 key购买 nike

我的应用程序应该能够将自定义元数据条目写入 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-specific metadata constants建议它应该成功。

我的应用程序应该使用 PNG 来避免 JPG's lossy compression .

为什么我不能在 iOS 中的内存中 PNG 图像上设置自定义元数据?

注意:我看过this SO question , 但这里并没有解决具体如何将元数据写入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 字段设置成功。

enter image description here

但是如果您尝试读取这个新文件的元数据,kCGImagePropertyPNGDescription 将会丢失。

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

经过一些研究,我发现 PNG 不包含元数据。但它可能包含 XMP metadata .然而,ImageIO 似乎不适用于 XMP。
也许你可以尝试使用 ImageMagiclibexif .

有用的链接:
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 - 如何在 iOS 中将自定义元数据写入 PNG 图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15212083/

26 4 0
文章推荐: ios - NSJSON 序列化错误?
文章推荐: css - 如何使用 Bootstrap 将按钮居中对齐
文章推荐: jquery - 如何使用 jQuery 删除
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com