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

查看:538
本文介绍了如何从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并将其作为图像文件保存到文件系统中,则应该从不使用lockFocus创建一个新图像,该图像确定要在屏幕上显示,而别无其他.因此,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天全站免登陆