在外部下载的PNG图片上执行iPhone优化

7
当PNG被添加到XCode iPhone项目中时,编译器使用pngcrush对其进行优化。一旦在设备上,图像的渲染性能非常快。
我的问题是,我的应用程序在运行时从外部源(从Picasa Web相册,使用Google Data API)下载其PNG。不幸的是,这些图片的性能非常差。当我在图像顶部进行自定义渲染时,它似乎比其内部存储的对应物慢100倍。我强烈怀疑这是因为下载的图像没有被优化。
有人知道如何在iPhone上在运行时优化外部下载的PNG吗?我希望有一个可以做到这一点的类。我甚至考虑将pngcrush的源代码添加到我的应用程序中,这似乎是极端的。我自己找不到一个合适的答案。我将非常感谢任何帮助。
谢谢!
更新: 有些人认为可能是文件大小的问题,但事实并非如此。在我的测试中,我添加了一个切换按钮,可以在嵌入版本和下载版本之间切换完全相同的PNG。唯一的区别是,嵌入式版本在编译期间通过“pngcrush”进行了优化。这会进行一些字节交换(从RGBA到BRGA)和alpha预乘。(http://iphonedevelopment.blogspot.com/2008/10/iphone-optimized-pngs.html
此外,我所指的性能不是下载,而是渲染。我在图像上叠加自定义绘画(覆盖UIView的drawRect方法),当背景是下载版本时,它非常卡顿,而当背景是嵌入式(因此经过优化)版本时,它非常流畅。再次强调,它是完全相同的文件。唯一的区别是优化,我希望可以在设备上,在下载后运行时对图像进行优化。
再次感谢大家的帮助!

我认为在渲染时(比如第一次之后),不应该触碰原始的PNG数据,所以我真的不知道它如何会有很大的差异。也许像Andrew Grant所建议的那样,这是由于图像大小的问题? - Jesse Rusak
需要注意的是,虽然只需要运行一次pngcrush等价的过程,但仍需要运行,因此在那个时候会有性能影响。 - Kieren Johnstone
7个回答

7

你发布的链接基本上回答了你的问题。

XCode在构建过程中对png进行预处理,使其更适合iPhone的图形芯片格式。

没有经过这种处理的png可能会使用较慢的渲染路径,其中处理非本地格式和必须为每种颜色单独计算alpha的事实。

所以你有两个选择:

  1. 执行与pngcrush相同的工作并交换排序/预乘alpha。加速可能是由于其中一个或两个原因造成的。

  2. 在加载图像后,您可以从中“创建”新图像。此新图像应该是iPhone的本机格式,因此应该执行得更快。缺点是它可能会占用更多内存。

例如:

CGRect area = CGRectMake(0, 0, width, height);
CGSize size = area.size;
UIGraphicsBeginImageContext(size);

[oldImage drawInRect:area];

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

3

你说它“似乎”慢了100倍,这表明你没有进行任何实验,只是猜测(一定是PNG优化),现在基于直觉走下了一条路。

在尝试解决问题之前,你应该花时间确认问题所在。我的直觉告诉我,PNG优化不应该是问题:它主要影响图像的加载,但一旦它们在内存中,原始文件格式就无关紧要了。

无论如何,你应该尝试进行A-B比较,要么从其他地方加载优化后的PNG并查看其效果,要么制作一个测试应用程序,对两种PNG类型进行绘图。一旦你确认了问题所在,那么你就可以确定是否需要将pngcrush编译到你的应用程序中。


嘿,我已经进行了这个比较。我有一个切换按钮,可以让我在下载版本和相同PNG的嵌入版本之间交换屏幕上的图像,差异非常大。优化如下所示:http://tinyurl.com/6fnsmt - Dan Bourque

2

表面上看,这里似乎还有其他因素在起作用。任何额外的图像处理都应该只会增加到屏幕显示所需的时间...

是否可能通过发送适当的HTTP头使服务器对图像进行gzip压缩?(如果它确实能够减小文件大小的话。)

暂时使用pngcrush源代码也可能是一个不错的测试方法,以获取一些测量数据。


谢谢您的建议;我想我会尝试使用pngcrush来测试这个概念。从服务器下载文件并显示它非常快,只需要发生一次。性能问题出现在我将自定义渲染叠加在UIImage上时。 - Dan Bourque
嗯,可能是所有额外的层叠在一起导致性能下降。有没有可能将这些叠加的图像合并成一个叠加层?目前,我正在用带有单个覆盖PNG的JPG执行类似操作,性能非常好。 - Collin Allen
嗯,事情是这样的,当使用图形的优化版本时性能非常好,但使用完全相同的下载版本时性能非常差。这就是为什么我确信分层与此无关的原因。 - Dan Bourque
啊,说得好!我想你没有控制服务器端(预压缩PNG文件)的权限吧... - Collin Allen

1

尝试使用pincrush将普通的png文件转换为压缩的png文件


1
你是否以原始下载大小存储PNG文件?如果是大图像,渲染时间会显著延长。

好的想法,但是下载的图像与嵌入的图像大小和分辨率完全相同。事实上,它们是完全相同的图像。 - Dan Bourque

1
好吧,看起来一个很好的方法(因为你不能在iPhone上运行pngcrush并期望其加速),就是通过运行pngcrush的代理来进行请求。代理将具有良好的计算能力,实际上可以使您感到比100倍的痛苦更有所收获。

0

你说你正在覆盖一个UIView的drawRect:方法来在图像上绘制。你是想通过反复在图片上绘制整个带有自定义内容的图像来实现一些动画效果吗?

如果你把自定义的内容放在一个单独的视图或者图层中,并让操作系统处理将结果合成到背景上,你可能会得到更好的效果。操作系统只会更新你实际改变的屏幕部分,并不会频繁地重新绘制整个图像。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接