iOS开发之加载、滑动翻阅大量图片优化解决方案

本文转载至 http://mobile.51cto.com/iphone-413267.htm

今天分享一下私人相册中,读取加载、滑动翻阅大量图片解决方案,我想强调的是,编程思想无关乎平台限制。我要详细说一下,在缩略图界面点击任意小缩略图后,进入高清大图全屏浏览界面的这短暂的1秒内(和后续的几秒),都发生了什么。

AD:2014WOT全球软件技术峰会北京站 课程视频发布

今天分享一下私人相册中,读取加载、滑动翻阅大量图片解决方案,我想强调的是,编程思想无关乎平台限制。

我要详细说一下,在缩略图界面点击任意小缩略图后,进入高清大图全屏浏览界面的这短暂的1秒内(和后续的几秒),都发生了什么。

常规思路流程

点击任意小图后,

1.首先制作scrollview框架:大小2个scrollview,小的用于手势缩放单一图片,大的横向依次加载全部照片

2.制作好scrollview框架后,加载照片

3.一切准备就绪跳转页面呈现给用户选择的大图

加载图片这一步,若相册内就10几张照片,那么毫无技术挑战,但是如果是300张照片呢?直接崩溃?还是让用户等待加载? 时间紧任务重,这一步需要拆分和优化.

scrollview框架需要了解下API,然后动动脑子了,这里有个小窍门,很多人都问我照片与照片间的黑边间距怎么实现,呵呵,贴下代码:

  1. #define PADDING  20
  2. - (NSInteger)loadPhotos
  3. {
  4. //清理之前照片
  5. for (UIView *v in [_scrollView subviews]) {
  6. [v removeFromSuperview];
  7. }
  8. workingFrame = [[UIScreen mainScreen]bounds];
  9. workingFrame.origin.x = PADDING;
  10. for (int i = 0; i < int_total; i++) {
  11. CGRect frame = workingFrame;
  12. WQPhoto *photoView = [[WQPhoto alloc] initWithFrame:frame];
  13. [photoView setScroller:self];
  14. [photoView setIndex:i];
  15. WQAlbumPhoto *photo = [albumObject._photos objectAtIndex:i];
  16. [photo cleanThumbnail];
  17. if (i == int_current) {
  18. //加载原图
  19. [photoView setImage:photo.oriImage];
  20. [photoView setIsLoad:YES];
  21. }else if (int_current - 10 < i && i < int_current + 10){
  22. //加载左右临近的缩略图
  23. [photoView setImage:photo.thumbnail4view];
  24. }
  25. [_scrollView addSubview:photoView];
  26. workingFrame.origin.x = workingFrame.origin.x + 2 * PADDING
  27. + workingFrame.size.width;
  28. }
  29. //实现可滚动
  30. [_scrollView setContentSize:CGSizeMake(workingFrame.origin.x, workingFrame.size.height / 2)];
  31. [_scrollView setContentOffset:CGPointMake(360 * int_current, 0)];
  32. //加载其余缩略图
  33. loadThread = [[NSThread alloc]initWithTarget:self selector:@selector(loadImages) object:nil];
  34. return 0;
  35. }

使用低分辨率图

仔细想想,其实没有必要第一时间加载全部图片的高清原图,事先存好每张图配套的低分辨率图,用空间换时间。

先加载所有的图片的低分辨率图, 当用户翻阅到某一张图片时, 即时的加载原始尺寸的高清无码大图. 过程优化为:

多线程任务

即使是这样,当照片数量达到一定量时,需要消耗的时间也并非毫秒级,体验无法领人满意,  页面跳转时仍然会出现卡顿现象。

于是考虑使用多线程来进一步拆分任务, 执行跳转的同时再后台执行加载低分辨率图的步骤.

优化快速翻阅体验

通过这样的拆分,可以实现立即跳转,体验满意。但是翻阅浏览时,当用户很快左右滑动时, 出现黑屏的几率很高, 因为加载低分辨率图任务的线程可能还在进行大量IO操作,不能及时跟上。 为了完善它,要把加载低分辨率图的步骤再次分解,精益求精。 
在页面跳转时间允许的范围内,加载用户选定的那张图片的高清原图的同时,尽可能多的加载几张左右临近的图片的低分辨率图。

如何加载其余的低分辨率图?

以用户点击选定的那张图为中心向两边加载, 直接想应该是两个线程一左一右的加载,再想想左右一起加载其实可以是一个循环, 免了再开线程的那些耗费了。

  1. -(BOOL)loadImages
  2. {
  3. for (int i = int_current - 10, j = int_current + 10 ; !( i < 0 &&  int_total - 1 < j); --i, ++j) {
  4. if (!(i < 0)) {
  5. WQPhoto *photo_pre = [_scrollView.subviews objectAtIndex:i];
  6. WQAlbumPhoto *photoPre = [albumObject._photos objectAtIndex:i];
  7. [photo_pre setImage:photoPre.thumbnail4view];
  8. }
  9. if (!(int_total - 1 < j)) {
  10. WQPhoto *photo_next = [_scrollView.subviews objectAtIndex:j];
  11. WQAlbumPhoto *photoNext = [albumObject._photos objectAtIndex:j];
  12. [photo_next setImage:photoNext.thumbnail4view];
  13. }
  14. }
  15. return YES;
  16. }

最后还一个砍儿

尽量减少内存占用.  因为原始图片要比低分辨率图大很多, 所以当用户从一张图片翻阅到另一张图片时,  当前图片加载为原始尺寸的高清大图, 而原来那张就被替换为低分辨率图了。 虽然读写次数增多了, 但内存确实省了不少。

实话说,市场上不少相册类的app, 翻阅时都会有卡顿的跳跃感,呵呵……

时间: 2024-10-28 02:35:56

iOS开发之加载、滑动翻阅大量图片优化解决方案的相关文章

iOS开发之加载大量网络图片优化

1.概述 在IOS下通过URL读一张网络图片并不像其他编程语言那样可以直接把图片路径放到图片路径的位置就ok,而是需要我们通过一段类似流的方式去加载网络图片,接着才能把图片放入图片路径显示.比如: -(UIImage *) getImageFromURL:(NSString *)fileURL {   //NSLog(@"执行图片下载函数");       UIImage * result;       NSData * data = [NSData dataWithContentsO

iOS开发-UIWebView加载本地和网络数据

UIWebView是内置的浏览器控件,可以用它来浏览网页.打开文档,关于浏览网页榜样可以参考UC,手机必备浏览器,至于文档浏览的手机很多图书阅读软件,UIWebView是一个混合体,具体的功能控件内置的,实现一些基本的功能.UIWebView可以查看Html网页,pdf文件,docx文件,txt文件文件,系统自带的Safari就是UIWebView实现的. 基础布局 页面布局很简单就是一个文本框,一个按钮,一个UIWebView,页面布局如下: 如果想简单一点的话,其实用UIWebView也行,

iOS开发_UIWebView加载本地html

项目中遇到这样的问题:webview放在uiscrollview,webview加载本地html,之后需要计算webview高度. 步骤如下: 1.首先创建webview.几点注意,高度一定要小于你要加载的html的高度,最好设定个最小值,比如1:并且设置scalesPageToFit = YES使之自适应高度; self.bottomWebView = [[UIWebView alloc]initWithFrame:CGRectMake(0, CGRectGetMaxY(self.middle

ios开发 uiwebview加载网页时阻止禁止取消图片下载

http://www.icab.de/blog/2009/08/18/url-filtering-with-uiwebview-on-the-iphone/ - (NSCachedURLResponse*)cachedResponseForRequest:(NSURLRequest*)request { NSURL *url = [request URL]; BOOL blockURL = [url.absoluteString hasSuffix:@"jpg"] || [url.ab

iOS开发——加载、滑动翻阅大量图片解决方案详解

加载.滑动翻阅大量图片解决方案详解 今天分享一下私人相册中,读取加载.滑动翻阅大量图片解决方案,我想强调的是,编程思想无关乎平台限制. 我要详细说一下,在缩略图界面点击任意小缩略图后,进入高清大图全屏浏览界面的这短暂的1秒内(和后续的几秒),都发生了什么. 常规思路流程 点击任意小图后, 1.首先制作scrollview框架:大小2个scrollview,小的用于手势缩放单一图片,大的横向依次加载全部照片 2.制作好scrollview框架后,加载照片 3.一切准备就绪跳转页面呈现给用户选择的大

Android开发--异步加载

因为移动端软件开发思维模式或者说是开发的架构其实是不分平台和编程语言的,就拿安卓和IOS来说,他们都是移动前端app开发展示数据和用户交互数据的数据终端,移动架构的几个大模块:UI界面展示.本地数据可持续化存储.网络数据请求.性能优化等等,安卓和IOS开发都要考虑这些架构的模块.所以,熟悉IOS的开发的人,再去学习一下安卓的开发以及安卓的开发模式,你会发现很多技术和思想安卓和IOS是一样的,只是可能说法不一样,由于编程语言比如OC和Java略微的差异性,编码习惯和细节不一样之外,其他都是一样的.

Android数据分批加载-滑动到底部自动加载列表

Android数据分批加载-滑动到底部自动加载列表 2014年5月9日 本博文介绍如何进行数据分批加载,在应用开发当中会经常使用到ListView,点击更多加载数据是我们经常简单,为了提供用户体验,当用户将列表滚动到底部自动加载数据,这样的形式用得比较多. 下面给大家提供的例子是,每次模拟20条数据,滑动到底部时再请求20条数据直到请求到限定页数为止 具体代码实现: /08_Datapageload/src/com/wwj/datapageload/MainActivity.java packa

【iOS】网络加载图片缓存与SDWebImage

加载网络图片可以说是网络应用中必备的.如果单纯的去下载图片,而不去做多线程.缓存等技术去优化,加载图片时的效果与用户体验就会很差. 一.自己实现加载图片的方法 tips: *iOS中所有网络访问都是异步的.(自己开线程去下载) *普通为模型增加UIImage属性的方法做的是内存缓存(下次启动还需要从网络重新加载), 而要做本地缓存的话,还要自己手动存储网络上下载的图片. *为了加快访问, 还需要自己去弄缓存.(内存缓存或者本地缓存) *当图片没有下载完成时,还要设置占位图片. 以下代码用NSOp

ios UITableView 异步加载图片并防止错位

UITableView 重用 UITableViewCell 并异步加载图片时会出现图片错乱的情况 对错位原因不明白的同学请参考我的另外一篇随笔:http://www.cnblogs.com/lesliefang/p/3619223.html . 当然大多数情况下可以用 SDWebImage, 这个库功能强大,封装的很好.但自己重头来写可能对问题理解的更深. SDWebImage 有点复杂,很多人也会参考一下封装出一套适合自己的类库. 基本思路如下: 1 扩展(category) UIImage