美文网首页好东西小知识点
谈谈 iOS 中图片的解压缩

谈谈 iOS 中图片的解压缩

作者: Crazy2015 | 来源:发表于2017-05-18 10:19 被阅读186次

图片加载的工作流

概括来说,从磁盘中加载一张图片,并将它显示到屏幕上,中间的主要工作流如下:

  1. 假设我们使用 +imageWithContentsOfFile: 方法从磁盘中加载一张图片,这个时候的图片并没有解压缩;
  2. 然后将生成的 UIImage 赋值给 UIImageView ;
  3. 接着一个隐式的 CATransaction 捕获到了 UIImageView 图层树的变化;
  4. 在主线程的下一个 run loop 到来时,Core Animation 提交了这个隐式的 transaction ,这个过程可能会对图片进行 copy 操作,而受图片是否字节对齐等因素的影响,这个 copy 操作可能会涉及以下部分或全部步骤:
    a. 分配内存缓冲区用于管理文件 IO 和解压缩操作;
    b. 将文件数据从磁盘读到内存中;
    c. 将压缩的图片数据解码成未压缩的位图形式,这是一个非常耗时的 CPU 操作;
    d. 最后 Core Animation 使用未压缩的位图数据渲染 UIImageView 的图层。

在上面的步骤中,我们提到了图片的解压缩是一个非常耗时的 CPU 操作,并且它默认是在主线程中执行的。那么当需要加载的图片比较多时,就会对我们应用的响应性造成严重的影响,尤其是在快速滑动的列表上,这个问题会表现得更加突出。

为什么需要解压缩

既然图片的解压缩需要消耗大量的 CPU 时间,那么我们为什么还要对图片进行解压缩呢?是否可以不经过解压缩,而直接将图片显示到屏幕上呢?答案是否定的。要想弄明白这个问题,我们首先需要知道什么是位图

A bitmap image (or sampled image) is an array of pixels (or samples). Each pixel represents a single point in the image. JPEG, TIFF, and PNG graphics files are examples of bitmap images.

其实,位图就是一个像素数组,数组中的每个像素就代表着图片中的一个点。我们在应用中经常用到的 JPEG 和 PNG 图片就是位图。下面,我们来看一个具体的例子,这是一张 PNG 图片,像素为 30 × 30 ,文件大小为 843B :

我们使用下面的代码

UIImage *image = [UIImage imageNamed:@"check_green"];
CFDataRef rawData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));

就可以获取到这个图片的原始像素数据,大小为 3600B :

事实上,不管是 JPEG 还是 PNG 图片,都是一种压缩的位图图形格式。只不过 PNG 图片是无损压缩,并且支持 alpha 通道,而 JPEG 图片则是有损压缩,可以指定 0-100% 的压缩比。值得一提的是,在苹果的 SDK 中专门提供了两个函数用来生成 PNG 和 JPEG 图片:

// return image as PNG. May return nil if image has no CGImageRef or invalid bitmap format
UIKIT_EXTERN NSData * __nullable UIImagePNGRepresentation(UIImage * __nonnull image);

// return image as JPEG. May return nil if image has no CGImageRef or invalid bitmap format. compression is 0(most)..1(least)                           
UIKIT_EXTERN NSData * __nullable UIImageJPEGRepresentation(UIImage * __nonnull image, CGFloat compressionQuality);

因此,在将磁盘中的图片渲染到屏幕之前,必须先要得到图片的原始像素数据,才能执行后续的绘制操作,这就是为什么需要对图片解压缩的原因。

强制解压缩的原理

既然图片的解压缩不可避免,而我们也不想让它在主线程执行,影响我们应用的响应性,那么是否有比较好的解决方案呢?答案是肯定的。

我们前面已经提到了,当未解压缩的图片将要渲染到屏幕时,系统会在主线程对图片进行解压缩,而如果图片已经解压缩了,系统就不会再对图片进行解压缩。因此,也就有了业内的解决方案,在子线程提前对图片进行强制解压缩。

而强制解压缩的原理就是对图片进行重新绘制,得到一张新的解压缩后的位图。其中,用到的最核心的函数是 CGBitmapContextCreate :

转载:http://blog.leichunfeng.com/blog/2017/02/20/talking-about-the-decompression-of-the-image-in-ios/

相关文章

  • iOS-图片解压缩相关

    SDWebimage中对图片的解压缩 谈谈 iOS 中图片的解压缩 iOS 开发:绘制像素到屏幕 探讨iOS 中图...

  • imageView的处理

    图片的处理参见谈谈 iOS 中图片的解压缩

  • 谈谈 iOS 中图片的解压缩

    谈谈 iOS 中图片的解压缩http://www.cocoachina.com/articles/18784

  • [iOS] 图片优化

    WWDC2018 图像最佳实践 iOS 处理图片的一些小 Tip 谈谈 iOS 中图片的解压缩 WWDC 2018...

  • 转载-谈谈 iOS 中图片的解压缩

    谈谈 iOS 中图片的解压缩 FEB 20TH, 2017 10:47 AM 对于大多数 iOS 应用来说,图片往...

  • 探讨iOS 中图片的解压缩到渲染过程

    探讨iOS 中图片的解压缩到渲染过程 探讨iOS 中图片的解压缩到渲染过程

  • 谈谈 iOS 中图片的解压缩

    ——————————————————转载自雷纯锋的技术博客 对于大多数 iOS 应用来说,图片往往是最占用手机内存...

  • 谈谈 iOS 中图片的解压缩

    图片加载的工作流 概括来说,从磁盘中加载一张图片,并将它显示到屏幕上,中间的主要工作流如下: 假设我们使用 +im...

  • 谈谈 iOS 中图片的解压缩

    对于大多数 iOS 应用来说,图片往往是最占用手机内存的资源之一,同时也是不可或缺的组成部分。将一张图片从磁盘中加...

  • iOS--博文收藏

    强烈推荐阅读大神博客--谈谈 iOS 中图片的解压缩 知识点: 位图:位图就是一个像素数组,数组中的每个像素就代表...

网友评论

    本文标题:谈谈 iOS 中图片的解压缩

    本文链接:https://www.haomeiwen.com/subject/abzjxxtx.html