如何从 NSImage 保存 PNG 文件(视网膜问题) [英] How to save PNG file from NSImage (retina issues)

查看:44
本文介绍了如何从 NSImage 保存 PNG 文件(视网膜问题)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在对图像进行一些操作,完成后,我想将图像以 PNG 格式保存在磁盘上.我正在做以下事情:

I'm doing some operations on images and after I'm done, I want to save the image as PNG on disk. I'm doing the following:

+ (void)saveImage:(NSImage *)image atPath:(NSString *)path {

    [image lockFocus] ;
    NSBitmapImageRep *imageRepresentation = [[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect(0.0, 0.0, image.size.width, image.size.height)] ;
    [image unlockFocus] ;

    NSData *data = [imageRepresentation representationUsingType:NSPNGFileType properties:nil];
    [data writeToFile:path atomically:YES];
}

此代码有效,但问题出在视网膜 mac 上,如果我打印 NSBitmapImageRep 对象,我会得到不同的大小和像素矩形,当我的图像保存在磁盘上时,它的大小是原来的两倍:

This code is working, but the problem is with retina mac, if I print the NSBitmapImageRep object I get a different size and pixels rect and when my image is saved on disk, it's twice the size:

$0 = 0x0000000100413890 NSBitmapImageRep 0x100413890 Size={300, 300} ColorSpace=sRGB IEC61966-2.1 colorspace BPS=8 BPP=32 Pixels=600x600 Alpha=YES Planar=NO Format=0 CurrentBacking=<CGImageRef: 0x100414830>

我绑定到强制像素大小不关心视网膜比例,因为我想保留原始大小:

I tied to force the pixel size to not take care about the retina scale, as I want to preserve the original size:

imageRepresentation.pixelsWide = image.size.width;
imageRepresentation.pixelsHigh = image.size.height;

这次我在打印 NSBitmapImageRep 对象时得到了正确的大小,但是当我保存我的文件时,我仍然遇到同样的问题:

This time I get the right size when I print the NSBitmapImageRep object, but when I save my file I still get the same issue:

$0 = 0x0000000100413890 NSBitmapImageRep 0x100413890 Size={300, 300} ColorSpace=sRGB IEC61966-2.1 colorspace BPS=8 BPP=32 Pixels=300x300 Alpha=YES Planar=NO Format=0 CurrentBacking=<CGImageRef: 0x100414830>

知道如何解决此问题并保留原始像素大小吗?

Any idea how to fix this, and preserve the original pixel size?

推荐答案

如果你有一个 NSImage 并且想将它作为图像文件保存到文件系统,你应该永远不要strong> 使用 lockFocuslockFocus 创建一个新图像,该图像被确定为显示在屏幕上,而不是其他任何东西.因此,lockFocus 使用屏幕的属性:普通 屏幕为 72 dpi,retina 屏幕为 144 dpi.对于您想要的,我建议使用以下代码:

If you have an NSImage and want to save it as an image file to the filesystem, you should never use lockFocus! lockFocus creates a new image which is determined for getting shown an the screen and nothing else. Therefore lockFocus uses the properties of the screen: 72 dpi for normal screens and 144 dpi for retina screens. For what you want I propose the following code:

+ (void)saveImage:(NSImage *)image atPath:(NSString *)path {

   CGImageRef cgRef = [image CGImageForProposedRect:NULL
                                            context:nil
                                              hints:nil];
   NSBitmapImageRep *newRep = [[NSBitmapImageRep alloc] initWithCGImage:cgRef];
   [newRep setSize:[image size]];   // if you want the same resolution
   NSData *pngData = [newRep representationUsingType:NSPNGFileType properties:nil];
   [pngData writeToFile:path atomically:YES];
   [newRep autorelease];
}

这篇关于如何从 NSImage 保存 PNG 文件(视网膜问题)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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