求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
iOS开发——加载、滑动翻阅大量图片解决方案详解
 

作者:念茜,发布于2012-12-26,来源:CSDN

 

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

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

常规思路流程

点击任意小图后,

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

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

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

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

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

#define PADDING  20
- (NSInteger)loadPhotos
{
    //清理之前照片
    for (UIView *v in [_scrollView subviews]) {
        [v removeFromSuperview];
    }

    workingFrame = [[UIScreen mainScreen]bounds];
    workingFrame.origin.x = PADDING;
    
    for (int i = 0; i < int_total; i++) {
        CGRect frame = workingFrame;
        WQPhoto *photoView = [[WQPhoto alloc] initWithFrame:frame];
        [photoView setScroller:self];
        [photoView setIndex:i];

        WQAlbumPhoto *photo = [albumObject._photos objectAtIndex:i];
        [photo cleanThumbnail];
        if (i == int_current) {
	//加载原图
            [photoView setImage:photo.oriImage];
            [photoView setIsLoad:YES];
        }else if (int_current - 10 < i && i < int_current + 10){
	//加载左右临近的缩略图
            [photoView setImage:photo.thumbnail4view];
        }

        [_scrollView addSubview:photoView];
        workingFrame.origin.x = workingFrame.origin.x + 2 * PADDING 
+ workingFrame.size.width;
    }
    
    //实现可滚动
    [_scrollView setContentSize:CGSizeMake(workingFrame.origin.x, workingFrame.size.height / 2)];
    [_scrollView setContentOffset:CGPointMake(360 * int_current, 0)];
    //加载其余缩略图
    loadThread = [[NSThread alloc]initWithTarget:self selector:@selector(loadImages) object:nil];
    return 0;
} 

使用低分辨率图

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

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

多线程任务

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

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

优化快速翻阅体验

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

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

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

-(BOOL)loadImages
{
    for (int i = int_current - 10, j = int_current + 10 ; !( i < 0 &&  int_total - 1 < j); --i, ++j) {
        if (!(i < 0)) {
            WQPhoto *photo_pre = [_scrollView.subviews objectAtIndex:i];
            WQAlbumPhoto *photoPre = [albumObject._photos objectAtIndex:i];
            [photo_pre setImage:photoPre.thumbnail4view];
        }
        if (!(int_total - 1 < j)) {
            WQPhoto *photo_next = [_scrollView.subviews objectAtIndex:j];
            WQAlbumPhoto *photoNext = [albumObject._photos objectAtIndex:j];
            [photo_next setImage:photoNext.thumbnail4view];
        }
    }
    return YES;
} 

最后还一个砍儿

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

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


 
分享到
 
 


android人机界面指南
Android手机开发(一)
Android手机开发(二)
Android手机开发(三)
Android手机开发(四)
iPhone消息推送机制实现探讨
手机软件测试用例设计实践
手机客户端UI测试分析
手机软件自动化测试研究报告
更多...   


Android高级移动应用程序
Android应用开发
Android系统开发
手机软件测试
嵌入式软件测试
Android软、硬、云整合


领先IT公司 android开发平台最佳实践
北京 Android开发技术进阶
某新能源领域企业 Android开发技术
某航天公司 Android、IOS应用软件开发
阿尔卡特 Linux内核驱动
艾默生 嵌入式软件架构设计
西门子 嵌入式架构设计
更多...