如何从NSImage保存PNG文件(视网膜问题) [英] How to save PNG file from NSImage (retina issues)
问题描述
我正在对图像进行一些操作,完成后,我想将图像另存为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屋!