Pholio应用开发指南:通过平铺组成大的图片

本文翻译自Brian's Brain的Pholio Coder's Guide: Tiling Large Images

在我开发Pholio应用时,我面临其中一个最大的挑战就是处理超大图片。摄影师通常会使用[Camera Connection Kit][2]
[2]:http://store.apple.com/us/product/MC531ZM/A/apple-ipad-camera-connection-kit
这款连接工具来把他们的全分辨率图片上传到自己的iPad上。而显示全分辨率的照片会耗用大量的内存 - 大概是每一百万像素占用4M内存。所以,例如用1600万像素的D7000相机拍出的相片,在完全显示时会占用64MB内存。如果一个摄影师使用的是只有256MB内存的iPad 1,即使只是显示一张全像素的照片都会非常吃力。而为了流畅滑动,需要你加载多张照片在内存中,那这种情况下,你会怎么做呢?

尝试 #1:平铺

我的第一个尝试是把大图片分隔成一张张的小图片,在使用小图片时,可以高效地利用内存,但同时用户还是可以通过放大来查看大图片的细节。这样之所以能够行得通,是因为你再放大图片来查看高分辨率下的细节时,你查看的并不是整张图片。如果你把高分辨率的图片分隔成一张张,只显示需要用的小张图片,那么这样就不需要完全加载一整张图片到内存中了。

下面的图片向你展示了Pholio应用如何在大图片上应用平铺的一个思路。从全分辨率的照片开始,我先计算到底需要提供多少程度的细节,每种级别的细节都是前一个细节分辨率的四分之一(也就是每一边的一半大小)。最高级别的细节就是全分辨率的照片;最低级别的细节将会是刚好填充屏幕的图片。然后,我会重新调整图像到合适的大小,最后把它分成固定大小的块。每一块都会单独保存为PNG格式(你可以在[IPPhoto.m][3]文件找到源码,开始于 -[IPPhoto saveTilesForAllScales],方法里面的核心源代码来自一个很棒的教程[Cocoa is my Girlfriend][4])。
[3]:https://github.com/bdewey/Pholio/blob/master/Classes/IPPhoto.m
[4]:http://www.cimgf.com/2011/03/01/subduing-catiledlayer/

一旦我把图片分隔成一张张小图片后,我利用一个自定义的子类UIView来显示这张图片。这个IPPhotoTilingView子类,使用CGTiledLayer 来把我之前保存的小张图片高效地显示在屏幕上。可以看到使用平铺的唯一缺陷就是在图片第一次显示的时候,各个小张图片整合在一起时像是网络相册;你可以在小张图片之间看到明显的边框。

我在Pholio2.0.2版本中使用了这个策略来处理大张图片。按照需求,我会创建一个后台线程去产生一张张小图片。我特地先生成最低级别的细节图片,这样我可以最大限度地响应用户的操作。我编写代码来确保在没有完成分隔图片之前,用户不能缩放图片。在我的测试中和我的设备上一切运行良好。我为自己感到骄傲。


插曲:iPad 1

在2.0版本发布后,我经历了每个开发者都会害怕的时刻:一个用户联系我说,这个应用崩溃了。在我和他之间通了几封邮件后,我明白为什么了:他在iPad 1上试图显示10万像素的图片,而我的所有测试都是在iPad 2上做的,iPad 2的内存是iPad 1的两倍。

我开始在iPad 1上测试显示全分辨率照片,我发现了这个用户所遇到的情况。分隔图片的过程在这个设备上轻易就会导致内存耗尽。如果你还没有发现的话,让我告诉你吧:没有什么比在调试内存错误时,发现原来你需要更多地内存更令人沮丧了。

我需要想另一个方法了。在我的下一篇文章中,我将介绍一种在2.1版本中更保守处理大图片的方法。

posted @ 2014-05-17 20:47  剑尖  阅读(286)  评论(0编辑  收藏  举报