当前位置:首页 > 技术心得 > 正文内容

获取NSImage图片的准确大小

xjtudll11年前 (2016-01-07)技术心得18820

问题:

NSImage加载图片的时候无法准确获得图片的大小

测试代码:

NSImage *image = [NSImage imageNamed:@"image"];

NSLog(@"%f, %f", image.size.width, image.size.height);

//终端Log到的图片的尺寸是:185.250000, 106.500000,而实际的大小是274.0, 142.0。

//image.size = NSMakeSize(247.0, 142.0); //强制指定尺寸能够解决问题

分析:

用一个Image Well来显示图片的时候,发现图片居然比实际的要小!我试着NSLog图片的大小,发现NSImage加载的图片的size根本就是错的!我根据图片的实际大小,强制设置了图片的尺寸,图片就显示正常了,而且也没有被拉伸的痕迹。这说明图片数据在加载后并没有损耗,只是图片的size属性出错了,因此,强制设置size属性,图片就能正常显示了。

在搜索了一番之后,发现这个问题似乎和图片的DPI有关。如果图片的DPI不是72,NSImage加载图片后size属性就会出错。我在iOS上用同样的方法做了测试,发现UIImage则没有类似的问题。虽然我对图片的DPI的概念也是一知半解,但是,像72 DPI这种应该算是历史的包袱了,毕竟Cocoa是一个非常古老的框架了。

虽然在这里,人肉设置图片大小能够解决问题,不过总不能在以后的代码中都人肉设置每张图片的尺寸吧。总有什么准确的方法来获取图片的真实像素尺寸的。然后就找到了Stack Overflow里的这个问题,解决方法是这样的:// 不要用这个方法,这个方法并不一定总能成功。

NSBitmapImageRep *rep = [[image representations] objectAtIndex: 0];

NSSize size = NSMakeSize([rep pixelsWide], [rep pixelsHigh]);

[image setSize: size];

我试了一下这个方法,确实能够解决我的问题。不过这个方法下面,两个开发人员的对话很有启发,其中一人提到了一个问题,那就是NSImage可能并不存在NSBitmapImageRep--这并不稀奇,比如,用Mac的摄像头拍下的图片就没有!因此,一定有更好的方法。

解决办法:

在Stack Overflow上找到了另一个更加靠谱的方法:

NSImage *image = [NSImage imageNamed:@"image"];

NSBitmapImageRep *rep = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]];

NSSize size = NSMakeSize([rep pixelsWide], [rep pixelsHigh]);

[image setSize: size];

至此,问题完美解决。不过这个问题提醒了我,不要对Cocoa的内建对象想当然,一定要注意Cocoa框架中的陷阱。这种方法其实在原理上和之前说的那个有缺陷的方法并没有非常本质的不同。只是这种方法是创建了一个NSBitmapImageRep,而不是从图片中获取一个。这样,就不会存在图片对象中无法获取NSBitmapImageRep的问题了。

扫描二维码推送至手机访问。

版权声明:本文由鸟的天空发布,如需转载请注明出处。

本文链接:http://xjtudll.cn/Exp/381/

标签: cocoa
分享给朋友:

“获取NSImage图片的准确大小” 的相关文章

手表防水扫盲

手表防水扫盲

手表防水的误区 很多人觉得奇怪,当要购买水中活动可以使用的手表时,为何推荐他们防水100m以上的手表。“我一辈子也没潜水超过50m”,其实,这样的疑问不只存在于一般购买手表的消费者身上,前几年多数的手表销售员与修表师傅也都不甚在意这个问题,直到最近运动表的市场受到重视,才开始注意防水标示的区别,但...

EEPROM读写注意事项

EEPROM读写注意事项

在实际使用EEPROM过程中,发现一些问题: 一、快速操作EEPROM造成读写数据出错 现象:读取的数据与写入的不同,但时序波形和硬件未发现任何问题。 在查阅EEPROM规格书后发现有一个很容易忽略的参数:TDHDL,此参数用于规定当对EEPROM进行一次I2C操作后必须再等待一段时间才能再对EEP...

贴片电阻电容电感封装尺寸

贴片电阻电容电感封装尺寸

贴片常见封装有9种,用两种尺寸代码来表示。一种尺寸代码是由4位数字表示的EIA(美国电子工业协会)代码,前两位与后两位分别表示电阻的长与宽,以英寸为单位。我们常说的0603封装就是指英制代码。另一种是米制代码,也由4位数字表示,其单位为毫米。下表列出贴片电阻封装英制和公制的关系及详细的尺寸。...

Android Warning: Converting to string: TypedValue …

参考资料:   http://stackoverflow.com/questions/4903948/android-resources-converting-to-string-typedvalue-warning   问题:   切换activity...

Altium pcb文件过大

Altium pcb文件过大

问题描述: 一些Altium Designer设计的文件看上去板子小且走线也不多,但是保存后文件却比较大。 原因: 通常是在PCB中放置了非默认字体的字符。 在软件里面有一个默认的选项“Embed  TrueType Fonts inside PCB Doc...

RDLC报表:不同的页眉

RDLC报表:不同的页眉

问题描述: RDLC报表,需要首页页眉和后面的页面页眉不同 解决办法: 利用Hidden属性和内置字段PageNumber。适当隐藏某些元素。 则可实现不同的页眉。 例如:某个元素仅第一页显示 参考资料: https://forums.asp.net/t/2031340.aspx?having+...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。