iOS压缩高清大图片

首先要知道为啥压缩大图片会内存暴增,然后降下来?(UIImageJPEGRepresentation,UIImagePNGRepresentation)

图片的压缩会瞬间消耗很大内存,apple官方文档对CGBitmapContextCreate函数的注解:

bitsPerComponent 表示存入内存中的每个像素中的每一个组件所占的位数;
bytesPerRow 表示存入内存中的位图的每一行所占的字节数;

解压缩操作中,每一个像素点都会分配一个空间来存储相关值,那么分辨率越高的图片,就意味着更多数量的像素点,也就意味着需要分配更多的空间!所以对于高分辨率图来说,解压缩操作的确会造成内存飙升,即使是几M的图片,解压缩过程中也是有可能消耗上G的内存!可以根据苹果官方的加载大图片例子得出结论,例子中有一句注释:

#define kImageFilename @"large_leaves_70mp.jpg" // 7033x10110 image, 271 MB uncompressed

large_leaves_70mp.jpg图片是7033x10110(占用磁盘大小8.3MB),分辨率 = 7033 x 10110 x 4(ARGB),对应位图占用大小 = 分辨率 x 1024 x 1024 ( = 271MB),解压会把图片转成位图,也就意味着会占用271MB内存,所以解压过程内存会瞬间消耗很大,等转成NSData后位图的内存就会被回收掉,内存就降下来,这时候NSData占用的大小即是图片的实际大小,该过程中由于会转成位图,而位图的大小是比图片的实际的大小大很多的,内存暴增的点就在位图。位图的内存大小计算是根据图片的分辨率而来(分辨率(width x heigth) x 1024 x 1024 x 4 (ARGB)),所以一般来说图片分辨率越高转成的位图占用的内存空间越大。

其次得知道压缩图片的目的,用于做啥?

这么一说感觉都用不到压缩了?一般的小图片当然还是要用到压缩,显示或上传,那如果非要压缩大图片呢?压缩大图片低设备肯定要挂,参考了苹果官方加载大图片的例子,大图片分成很多小片,利用GPU来处理每个小分片,最后显示,那么,大图片的压缩是不是也可以分片压缩呢?

答案是可以的,整体思路和图片分片显示一样的:

  • 获取到某一图片分片(如果太大可以改变分片的大小到合适大小)

  • 对获取到的图片分片压缩,压缩得到的data可以直接使用NSFilehandle断点写入磁盘中(大图片相当于大文件,大文件的断点写入可以参考iOS大文件下载,断点下载),然后释放data,最好不要保存到内存中.

  • 等所有的图片分片都压缩完,自然也就压缩完。这时图片的data已经全部获取,接下来改干嘛就干嘛。

代码其实没多大变化,直接在苹果官方的加载图片的例子中修改,因为要用到苹果官方加载大图片例子中的图片分片

/** 循环获取到大图片的每个小分片*/
for( int y = 0; y < iterations; ++y ) {
            @autoreleasepool {
                NSLog(@"iteration %d of %d",y+1,iterations);
               /** sourceTile大图片每个分片大小*/
               sourceTile.origin.y = y * sourceTileHeightMinusOverlap + sourceSeemOverlap;
                destTile.origin.y = ( destResolution.height ) - ( ( y + 1 ) * sourceTileHeightMinusOverlap * imageScale + destSeemOverlap );
               /** 大图片的一个小分片sourceTileImageRef*/
               sourceTileImageRef = CGImageCreateWithImageInRect( sourceImage.CGImage, sourceTile );
                /** 这边是保存到内存中,图片大小45MB左右,最后iphone4s内存在65MB左右,还是可以接受的,但是根据业务的需求,最好是把data写入磁盘中去,而不是保存到内存,我这边是偷懒了一下。*/
//                [UIImagePNGRepresentation([[UIImage alloc] initWithCGImage:sourceTileImageRef]) writeToFile:path atomically:YES];
                [bigData appendData:UIImagePNGRepresentation([[UIImage alloc] initWithCGImage:sourceTileImageRef])];
                if( y == iterations - 1 && remainder ) {
                    float dify = destTile.size.height;
                    destTile.size.height = CGImageGetHeight( sourceTileImageRef ) * imageScale;
                    dify -= destTile.size.height;
                    destTile.origin.y += dify;
                }
                
                CGContextDrawImage( destContext, destTile, sourceTileImageRef );
                CGImageRelease( sourceTileImageRef );
            }
            if( y < iterations - 1 ) {
                sourceImage = [[UIImage alloc] initWithContentsOfFile:imagePath];
                [self performSelectorOnMainThread:@selector(updateScrollView:) withObject:nil waitUntilDone:YES];
            }
        }

注意

上述压缩方式,会导致图片错乱,以为每次压缩生成的NSData时候一张分片图片,下一张分片图的NSData直接追加在上一张的后面iOS直接识别不了,我猜测一张完整的图片有开始标记和结尾标记,iOS系统在识别时只发现了第一张的开始标记和第一张的结束标记,这样iOS认为已经加载好了图片,就不会往下加载,故图片会错乱,只显示第一张分片的图片。这个是一个问题,还没解决。目前想到的是,每次压缩一个图片分片就保存到磁盘,最后把所有的图片合成一张。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容