将PNG添加到XCode iPhone项目时,编译器会使用pngcrush对其进行优化。一旦在设备上,图像的渲染性能非常快。
我的问题是我的应用程序在运行时从外部源下载PNG(使用Google Data API从Picasa网络相册中下载)。不幸的是,这些图像的表现非常糟糕。当我在图像上进行自定义渲染时,它似乎比内部存储的对应物慢100倍。我强烈怀疑这是因为下载的图像尚未优化。
有谁知道如何在iPhone上运行时优化外部下载的PNG?我希望有一个班级能做到这一点。我甚至考虑将pngcrush的源代码添加到我的应用程序中,这似乎很激烈。我自己一直无法找到合适的答案。我会非常感谢任何帮助。
谢谢!
更新: 有些人建议可能是由于文件的大小,但事实并非如此。在我的测试中,我添加了一个切换按钮,在使用嵌入版本和完全相同的PNG的下载版本之间切换。唯一的区别是嵌入的一个在编译期间由'pngcrush'优化。这会进行一些字节交换(从RGBA到BRGA)和alpha的预乘。 (http://iphonedevelopment.blogspot.com/2008/10/iphone-optimized-pngs.html)
另外,我所指的性能不是下载,而是渲染。我在图像顶部叠加自定义绘画(覆盖UIView的drawRect方法),当背景是下载版本时它非常不连贯,当它是嵌入(因此优化)版本时非常平滑。同样,它是完全相同的文件。唯一的区别是优化,我希望我可以在运行时,在设备上,在下载后对图像执行。
再次感谢大家的帮助!
答案 0 :(得分:7)
您发布的链接几乎可以回答您的问题。
在构建过程中,XCode会预处理你的png,因此它的格式对iPhone中的图形芯片更友好。
未经过这样处理的Png可能会使用较慢的渲染路径,一个处理非原生格式的路径,以及必须为每种颜色单独计算alpha的事实。
所以你有两个选择;
执行与pngcrush相同的工作并交换排序/预乘alpha。加速可能是由于这些中的一个或两个。
加载图像后,可以从中“创建”新图像。这个新图像应该是iPhone的原生格式,所以应该更快。缺点是它可能会占用更多的内存。
E.g。
CGRect area = CGRectMake(0, 0, width, height);
CGSize size = area.size;
UIGraphicsBeginImageContext(size);
[oldImage drawInRect:area];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
答案 1 :(得分:3)
你说它“似乎”慢了100倍这一事实表明你没有进行任何实验,但是做了一个猜测(它必须是PNG优化),现在正在基于预感走下去。
在尝试解决问题之前,您应该花些时间确认问题所在。我的直觉说PNG优化不应该是问题:这主要影响图像的加载,但一旦它们在内存中,它们最初所处的文件格式并不重要。
无论如何,您应该尝试进行A-B比较,或者让您的代码从其他地方加载优化的PNG,看看它是如何比较的,或者制作一个只对两种PNG类型进行绘制的测试应用程序。一旦你确认了问题所在,那么你可以弄清楚是否需要将pngcrush编译到你的应用程序中。
答案 2 :(得分:2)
从表面上看,这听起来像其他东西在这里发挥作用。任何额外的图像处理应该只添加时间,直到它显示在屏幕上...
是否可以让服务器通过发送适当的HTTP头来gzip图像? (如果它甚至可以帮助文件大小,那就是。)
暂时使用pngcrush源也可能是一个很好的测试,只是为了进行一些测量。
答案 3 :(得分:1)
您是否以原始下载大小存储png?如果它是一个大图像,渲染需要更长的时间。
答案 4 :(得分:1)
似乎这是一个很好的方法(因为你不能在iPhone上运行pngcrush并期望加速它)将通过运行pngcrush的代理发出请求。代理人将有很好的马力,实际上可以让你获得超过你所感受到的100倍痛苦的收益。
答案 5 :(得分:1)
尝试使用pincrush将普通的png文件转换为压缩的png文件
答案 6 :(得分:0)
你说你通过覆盖UIView的drawRect:
方法来绘制图像。您是否尝试通过在其上方使用自定义内容重复绘制整个图像来制作动画?
如果将自定义内容放在单独的视图或图层中,并让操作系统处理在后台合成结果,您可能会得到更好的结果。操作系统只会更新您实际更改的屏幕部分,并且不会经常重新绘制整个图像。