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

  

  

在移动应用开发过程中,图片往往是不可或缺的资源。从磁盘上加载一张图片,到显示到屏幕上,中间经过了一些复杂的过程,其中非常重要的一步就是对图片的解压缩。下面来一起看看详细的介绍吧

  

  

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

  

通常计算机在显示是CPU与GPU协同合作完成一次渲染。接下来我们了解一下CPU/GPU等在这样一次渲染过程中,具体的分工是什么& # 63;

  
      <李> CPU:计算视图框,图片解码,需要绘制纹理图片通过数据总线交给GPU李   <李> GPU:纹理混合,顶点变换与计算,像素点的填充计算,渲染到帧缓冲区。   <李>时钟信号:垂直同步信号V-Sync/水平同步信号H-Sync。   <李> iOS设备双缓冲机制:显示系统通常会引入两个帧缓冲区,双缓冲机制李   
  

<强>图片显示到屏幕上是CPU与GPU的协作完成
  

  

对应应用来说,图片是最占用手机内存的资源,将一张图片从磁盘中加载出来,并最终显示到屏幕上,中间其实经过了一系列复杂的处理过程。
  

  

  

1,假设我们使用+ imageWithContentsOfFile:方法从磁盘中加载一张图片,这个时候的图片并没有解压缩;
  

  

2,然后将生成的界面图像赋值给UIImageView;
  

  

3,接着一个隐式的CATransaction捕获到了UIImageView图层树的变化;

  

4,在主线程的下一个runloop到来时,核心动画提交了这个隐式的交易,这个过程可能会对图片进行复制操作,而受图片是否字节对齐等因素的影响,这个拷贝操作可能会涉及以下部分或全部步骤:

  
      <李>分配内存缓冲区用于管理文件IO和解压缩操作,李   <李>将文件数据从磁盘读到内存中,李   <李>将压缩的图片数据解码成未压缩的位图形式,这是一个非常耗时的CPU操作,李   <李>最后核心动画中CALayer使用未压缩的位图数据渲染UIImageView的图层。   <李> CPU计算好图片的框架,对图片解压之后。就会交给GPU来做图片渲染李   
  

5,渲染流程

  
      <李> GPU获取获取图片的坐标李   <李>将坐标交给顶点着色器(顶点计算)   <李>将图片光栅化(获取图片对应屏幕上的像素点)   <李>片元着色器计算(计算每个像素点的最终显示的颜色值)   <李>从帧缓存区中渲染到屏幕上李   
  

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

  


  

  

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

  

其实,位图就是一个像素数组,数组中的每个像素就代表着图片中的一个点。我们在应用中经常用到的JPEG和PNG图片就是位图
  

  

大家可以尝试
  

        用户界面图像*图像=[界面图像imageNamed: @“text.png”);   CFDataRef rawData=https://www.yisu.com/zixun/CGDataProviderCopyData (CGImageGetDataProvider (image.CGImage));      

打印rawData,这里就是图片的原始数据。
  

  

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

     //返回PNG的形象。可能返回nil如果图像没有CGImageRef或无效的位图格式   UIKIT_EXTERN NSData * __nullable UIImagePNGRepresentation(用户界面图像* __nonnull形象);//返回JPEG的形象。可能返回nil如果图像没有CGImageRef或无效的位图格式。压缩是0(大多数). . 1(至少)   UIKIT_EXTERN NSData * __nullable UIImageJPEGRepresentation(用户界面图像* __nonnull形象,CGFloat compressionQuality);      

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

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