Objective c 目标c-如何在保存JPEG文件时以编程方式设置其UIImage DPI

Objective c 目标c-如何在保存JPEG文件时以编程方式设置其UIImage DPI,objective-c,uiimage,metadata,Objective C,Uiimage,Metadata,我已经读到,您可以更改图像的元数据,以将dpi设置为默认值以外的其他值。我在年尝试了这个解决方案,但遇到了与问题作者相同的问题。原始图像中的图像元数据属性似乎优先于修改 我正在使用我的iPhone上的照片库来写入图像。我需要将dpi设置为500,而不是标准的72dpi。我知道可以通过直接操作位()来更改属性,但我希望iOS能提供更好的解决方案 提前感谢您的帮助。这段操作图像元数据的代码-如果存在-您可以使用它更改图像元数据中的任何值。请注意,更改元数据中的DPI值实际上不会处理图像并更改DPI

我已经读到,您可以更改图像的元数据,以将dpi设置为默认值以外的其他值。我在年尝试了这个解决方案,但遇到了与问题作者相同的问题。原始图像中的图像元数据属性似乎优先于修改

我正在使用我的iPhone上的照片库来写入图像。我需要将dpi设置为500,而不是标准的72dpi。我知道可以通过直接操作位()来更改属性,但我希望iOS能提供更好的解决方案


提前感谢您的帮助。

这段操作图像元数据的代码-如果存在-您可以使用它更改图像元数据中的任何值。请注意,更改元数据中的DPI值实际上不会处理图像并更改DPI

#import <ImageIO/ImageIO.h>


-(NSData *)changeMetaDataInImage
{
    NSData *sourceImageData = [[NSData alloc] initWithContentsOfFile:@"~/Desktop/1.jpg"];
    if (sourceImageData != nil)
    {
        CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)sourceImageData, NULL);

        NSDictionary *metadata = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);

        NSMutableDictionary *tempMetadata = [metadata mutableCopy];
        [tempMetadata setObject:[NSNumber numberWithInt:300] forKey:@"DPIHeight"];
        [tempMetadata setObject:[NSNumber numberWithInt:300] forKey:@"DPIWidth"];

        NSMutableDictionary *EXIFDictionary = [[tempMetadata objectForKey:(NSString *)kCGImagePropertyTIFFDictionary] mutableCopy];
        [EXIFDictionary setObject:[NSNumber numberWithInt:300] forKey:(NSString *)kCGImagePropertyTIFFXResolution];
        [EXIFDictionary setObject:[NSNumber numberWithInt:300] forKey:(NSString *)kCGImagePropertyTIFFYResolution];

        NSMutableDictionary *JFIFDictionary = [[NSMutableDictionary alloc] init];
        [JFIFDictionary setObject:[NSNumber numberWithInt:300] forKey:(NSString *)kCGImagePropertyJFIFXDensity];
        [JFIFDictionary setObject:[NSNumber numberWithInt:300] forKey:(NSString *)kCGImagePropertyJFIFYDensity];
        [JFIFDictionary setObject:@"1" forKey:(NSString *)kCGImagePropertyJFIFVersion];

        [tempMetadata setObject:EXIFDictionary forKey:(NSString *)kCGImagePropertyTIFFDictionary];
        [tempMetadata setObject:JFIFDictionary forKey:(NSString *)kCGImagePropertyJFIFDictionary];

        NSMutableData *destinationImageData = [NSMutableData data];

        CFStringRef UTI = CGImageSourceGetType(source);

        CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)destinationImageData, UTI, 1, NULL);

        CGImageDestinationAddImageFromSource(destination, source,0, (__bridge CFDictionaryRef) tempMetadata);

        CGImageDestinationFinalize(destination);

        return destinationImageData;
    }
}
#导入
-(NSData*)changeMetaDataInImage
{
NSData*sourceImageData=[[NSData alloc]initWithContentsOfFile:@“~/Desktop/1.jpg]”;
如果(sourceImageData!=nil)
{
CGImageSourceRef source=CGImageSourceCreateWithData((uu桥CFDataRef)sourceImageData,NULL);
NSDictionary*元数据=(uuu桥u传输NSDictionary*)CGImageSourceCopyPropertiesAtIndex(源,0,NULL);
NSMutableDictionary*tempMetadata=[元数据mutableCopy];
[tempMetadata setObject:[NSNumber numberWithInt:300]forKey:@“DPIHeight”];
[tempMetadata setObject:[NSNumber numberWithInt:300]forKey:@“DPIWidth”];
NSMutableDictionary*EXIFDictionary=[[tempMetadata objectForKey:(NSString*)kCGImagePropertyTIFFDictionary]mutableCopy];
[EXIFDictionary setObject:[NSNumber numberWithInt:300]forKey:(NSString*)kCGImagePropertyTIFFXResolution];
[EXIFDictionary setObject:[NSNumber numberWithInt:300]forKey:(NSString*)KCGimagePropertyTyffyResolution];
NSMutableDictionary*JFIFDictionary=[[NSMutableDictionary alloc]init];
[JFIFDictionary setObject:[NSNumber numberWithInt:300]forKey:(NSString*)kCGImagePropertyJFIFXDensity];
[JFIFDictionary setObject:[NSNumber numberWithInt:300]forKey:(NSString*)kCGImagePropertyJFIFYDensity];
[JFIFDictionary setObject:@“1”forKey:(NSString*)kCGImagePropertyJFIFVersion];
[tempMetadata setObject:EXIFDictionary forKey:(NSString*)kCGImagePropertyTIFFDictionary];
[tempMetadata setObject:JFIFDictionary-forKey:(NSString*)kCGImagePropertyJFIFDictionary];
NSMutableData*destinationImageData=[NSMutableData];
CFStringRef UTI=CGImageSourceGetType(源);
CGImageDestinationRef destination=CGImageDestinationCreateWithData((uu桥CFMutableDataRef)destinationImageData,UTI,1,NULL);
CGImageDestinationAddImageFromSource(目标,源,0,(\uu桥CFDictionaryRef)临时元数据);
CGImageDestinationFinalize(目的地);
返回destinationImageData;
}
}

在尝试使用此解决方案导出JPEG时,我发现Photoshop不会将DPI视为已导出。事实证明,Photoshop主动忽略了JFIF头信息(事实上,当它写出JPEG时,甚至不导出它自己)

我完全抛弃了JFIF部分。大多数现代图像库都会首先查看TIFF/EXIF数据,因此包含这些数据(仅此)似乎效果良好。您的里程可能会有所不同,因此请务必测试尽可能多的出口目的地

但是,TIFF数据缺少
ResolutionUnit
标记,没有该标记,Photoshop将忽略
XResolution
YResolution
。它可以有三个值:

1=无绝对计量单位。用于可能具有非方形纵横比但没有有意义的绝对尺寸的图像。
2=英寸。
3=厘米。

DPI(每英寸点数)需要将分辨率单位设置为
2,例如:

[EXIFDictionary setObject:@(2) forKey:(NSString *)kCGImagePropertyTIFFResolutionUnit];

还有一件事……我怎样才能将更改后的NSData返回,而不是写入文件?有趣的是,我已经用photoshop和preview在我的计算机上测试了保存的图像,DPI看起来不错。正确,preview.app和photoshop都是。我发现了我的问题!!呜呼!!!我正在用图书馆把图像写出来。我使用的方法是采用参数ALAssetOrientation,而不是元数据字典。