Objective c 如何保存视网膜图像,NSBitmapImageRep

Objective c 如何保存视网膜图像,NSBitmapImageRep,objective-c,image,macos,png,retina-display,Objective C,Image,Macos,Png,Retina Display,我试图创建一个模拟mac osx内置屏幕截图工具的东西,如果在视网膜监视器(320x240)中拍摄屏幕截图,结果显示的图像与拍摄的图像大小相同,但它是视网膜,因为dpi为144 然而,无论我做什么,我似乎不能做同样的事情。我可以用完全相同的元数据、规格(据我所知)保存一个图像,它只会以两倍大小打开 这是来自内置屏幕截图图像的数据 这是我制作的图像中的数据 我看到的唯一区别是XMP exif数据不同。 但首先,我似乎不知道如何改变它,其次,我不认为这有什么意义,所以我认为我仍然没有看到一些东西

我试图创建一个模拟mac osx内置屏幕截图工具的东西,如果在视网膜监视器(320x240)中拍摄屏幕截图,结果显示的图像与拍摄的图像大小相同,但它是视网膜,因为dpi为144

然而,无论我做什么,我似乎不能做同样的事情。我可以用完全相同的元数据、规格(据我所知)保存一个图像,它只会以两倍大小打开

这是来自内置屏幕截图图像的数据

这是我制作的图像中的数据

我看到的唯一区别是XMP exif数据不同。 但首先,我似乎不知道如何改变它,其次,我不认为这有什么意义,所以我认为我仍然没有看到一些东西,使视网膜图像

我的理论是,有一个隐藏的标志,我错过了,告诉预览打开内置屏幕截图320x240,而不是它的像素大小,640x480

这是我的密码。nsimagexifdata似乎没有粘住

   NSBitmapImageRep *bmpImageRep = [[NSBitmapImageRep alloc]
                                    initWithBitmapDataPlanes:NULL
                                    pixelsWide:640
                                    pixelsHigh:480
                                    bitsPerSample:8
                                    samplesPerPixel:4
                                    hasAlpha:YES
                                    isPlanar:NO
                                    colorSpaceName:NSCalibratedRGBColorSpace
                                    bitmapFormat:NSAlphaFirstBitmapFormat
                                    bytesPerRow:0
                                    bitsPerPixel:0
                                    ];


   bmpImageRep.size=NSMakeSize(320,240);

   id profile = [NSData dataWithContentsOfFile: @"/Library/ColorSync/Profiles/Displays/Color LCD-FD6E9053-53B7-5224-5892-F9F7EC52CEF3.icc"];
   [bmpImageRep setProperty:NSImageColorSyncProfileData withValue:profile];

   NSDictionary *exif = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithInt:640], kCGImagePropertyExifPixelXDimension, [NSNumber numberWithInt:480], kCGImagePropertyExifPixelYDimension, nil];
   [bmpImageRep setProperty:NSImageEXIFData withValue:exif];

   NSGraphicsContext *bitmapContext = [NSGraphicsContext graphicsContextWithBitmapImageRep:bmpImageRep];
   [NSGraphicsContext saveGraphicsState];
   [NSGraphicsContext setCurrentContext: bitmapContext];

   NSRect bgRect = NSMakeRect(0,0,320,240);
   [myImage drawInRect:bgRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];

   [NSGraphicsContext restoreGraphicsState];


   NSData* pngData= [bmpImageRep representationUsingType:NSPNGFileType
                               properties:nil];
   return pngData;

结果是,OSX记录了使用屏幕截图工具捕获的图像,然后告诉Preview打开一半大小的图像。所以,实际上不可能创建一个在预览中打开一半大小的图像,除非您在某个地方弄乱了操作系统文件。但这并不重要,因为如果你在Chrome或其他应用程序中打开一张用截图工具拍摄的图片,除了预览,它也会以两倍大小打开。因此,这似乎只是苹果为预览+内置屏幕截图设计的特殊外壳

这当然是我个人的猜测,因为我实际上找不到任何文档或更多关于这方面的信息。但是,我可以告诉你,我创建了一个内置屏幕截图图像的精确副本。包括所有与图像相关联的元数据和属性,但在预览中它仍然以不同的方式打开

我尝试更改NSBitmapImageRef、CGImage、CGContext中的任何相关属性,以尝试获取此信息。也尝试更改NSEXIFP属性,但没有效果。(相关的,不管你在元数据中做了什么改变,它都不会改变实际的图像——结果它们只是标签。这是有道理的,因为我见过带有.jpeg扩展名的GIF)

这里有一篇文章说,有人将预览中打开的图像缩小,但这与我想做的恰恰相反


不管怎么说,经过大量的挖掘,我恐怕现在得把这个案子了结了。如果有人偶然发现并找到了解决方案,请给我发消息:)

屏幕截图信息似乎存储在文件系统的扩展属性中,而不是特定格式的图像元数据中。这些扩展属性将与文件副本或打开/保存(只要应用程序未明确更改属性)一起复制,但不会与仅内容副本(即创建新文件并复制原始文件的内容)一起复制

您可以使用xattr命令行工具列出文件的扩展属性。以下是您对屏幕截图的期望:

元数据:kMDItemIsScreenCapture 元数据:kMDItemScreenCaptureGlobalRect 元数据:kMDItemScreenCaptureType


sys/xattr.h是包含操作文件扩展属性所需功能的标题。

我发现可以拍摄屏幕截图,在photoshop中打开,编辑大小调整等,保存时仍将以预览中一半的大小打开。一种猜测是,他们正在使用一种特殊的颜色配置文件。在将内容粘贴到图像中时,photoshop警告我颜色配置文件将发生变化,但两个配置文件的名称完全相同。@rasmus是的,我也注意到了这一点。所有的元数据,每一位,都是一样的。但它在预览中仍然以一半大小打开--但仅预览。所以我放弃了:\