iPhone 上使用 UIImageView 进行图像缩放
我有一个由许多 UIImageView 组成的自定义视图。这些 UIImageView 的大小可能有所不同(从 200x200 到 50x50)。它们显示的图像(从 png 文件加载)以尽可能高的分辨率 (200x200) 存储在资源中,但经常以较低的分辨率显示。
目前,我只是以全分辨率加载 UIImageViews 图像,因此:
UIImage* anImage = [UIImage imageWithContentsOfFile:imagePathAndName]; // anImage is 200x200
aView = [[UIImageView alloc] initWithImage:anImage];
aView.frame = myFrame; // myFrame is 50x50
第一个问题,让 UIImageView 将图像从 200x200 缩小到 50x50 是否会带来性能损失(内存或 CPU 时间)?我的应用程序似乎并未使用大量内存或因此而减慢速度,但如果我可以加快速度或减少内存消耗,那将是一场胜利。
我尝试以编程方式缩放图像。像这样:
UIImage* anImage = [UIImage imageWithContentsOfFile:imagePathAndName]; // Image is UIGraphicsBeginImageContext( scaledSize ); // scaledSize is 50x50
CGRect scaledRect = CGRectMake( 0.0, 0.0, scaledSize.width, scaledSize.height );
[anImage drawInRect:scaledRect];
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext(); // Scaled image is now 50x50
UIGraphicsEndImageContext();
aView = [[UIImageView alloc] initWithImage:scaledImage];
aView.frame = myFrame; // myFrame is 50x50
首先以编程方式缩放图像似乎没有不良影响......直到我将其加载到我的 iPhone 4 上。看,UIImageView 的大小基于父视图的大小,(在 IB 中布局) ,是 iPhone 3G 屏幕的大小。遗憾的是,尽管 iPhone 4 的分辨率是 3G 的两倍,但在 iPhone 4 上运行时该视图的大小是相同的。因此,通过根据视图大小缩放图像,我最终使它们的分辨率低于 iPhone 4 上应有的分辨率,而且它们看起来有点蹩脚。
所以第二个问题是,以编程方式缩小图像是否有一些好处。如何利用 iPhone 4 上的额外像素?显然我不能根据我的观点的大小来决定。
I have a custom view which is composed of a number of UIImageViews. These UIImageViews can vary in size (from 200x200 down to 50x50). The images that they display (loaded from png files) are stored in resources at the highest possible resolution (200x200), but frequently are displayed at lower resolutions.
Currently I just load the UIImageViews with the images at full resolution, thus:
UIImage* anImage = [UIImage imageWithContentsOfFile:imagePathAndName]; // anImage is 200x200
aView = [[UIImageView alloc] initWithImage:anImage];
aView.frame = myFrame; // myFrame is 50x50
First question, is there any performance penalty (memory or CPU time) to just letting UIImageView scale down the images from say 200x200 to 50x50? It doesn't appear that my app is using a ton of memory or slowing down as a result of this, but if I could speed it up or reduce memory consumption, that would be a win.
I played around with scaling the images programmatically. Like this:
UIImage* anImage = [UIImage imageWithContentsOfFile:imagePathAndName]; // Image is UIGraphicsBeginImageContext( scaledSize ); // scaledSize is 50x50
CGRect scaledRect = CGRectMake( 0.0, 0.0, scaledSize.width, scaledSize.height );
[anImage drawInRect:scaledRect];
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext(); // Scaled image is now 50x50
UIGraphicsEndImageContext();
aView = [[UIImageView alloc] initWithImage:scaledImage];
aView.frame = myFrame; // myFrame is 50x50
Programmatically scaling the images first seemed to have no ill affect... until I loaded it on my iPhone 4. See, the size of the UIImageView is based on the size if it's parent view, which (layed out in IB), is the size of an iPhone 3G screen. Sadly, the size of this view when running on an iPhone 4 is the same, despite the fact that the iPhone 4 has twice the resolution as a 3G. So by scaling the images based on the size of the view, I end up making them lower resolution than they should be on an iPhone 4, and they look kinda crappy.
So the second question is, if there is some benefit to programmatically scaling the images down. how can I take advantage of the extra pixels on an iPhone 4? Clearly I can't go by the size of my view.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
避免过早优化。
如果您的应用运行良好,它就会运行良好。如果没有,请尝试优化它。
根据我的经验,使用 200 像素的图像就可以了,而 50 像素的图像就可以了。图像可以轻松加载到图形硬件,并且缩放很可能在硬件中完成。
如果性能分析告诉我,我只会预缩放图像。
对于问题的第二部分,即实际的缩放代码,您必须注意,CoreGraphics 对视网膜显示一无所知。因此,在 CGBitmapContext 中,一个点是一个像素,除非您另有说明。在您的代码片段中,您遗漏了创建位图上下文的行,但它很可能是
UIGraphicsBeginImageContext(CGSize size)
。查看并使用 UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale); 来代替。通常应该传递 0.0 作为比例。UIKit 函数:UIGraphicsBeginImageContextWithOptions
Avoid premature optimization.
If your app runs well, it runs well. If it doesn't, try to optimize it.
From my experience using a 200px image where a 50px image would do is just fine. The image could easily be loaded to the graphics hardware and scaling is most likely done in hardware.
I would only prescale images if performance profiling tells me to.
For the second part of your question, the actual scaling code, you have to note, that CoreGraphics knows nothing about retina displays. So in a CGBitmapContext a point is a pixel, unless you tell it otherwise. In you code snippet you left out the line, which creates the bitmap context, but it's most likely
UIGraphicsBeginImageContext(CGSize size)
. Take a look at and useUIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale);
instead. Passing 0.0 as scale should normally do.UIKit Functions: UIGraphicsBeginImageContextWithOptions