跟着事务和功用的不断迭代更新, App的安装包巨细也在不断的添加. 初期或许特定功用的App或许不显着, 可是假如你想要你的App获得更好的用户体会, 那么减缩App安装包的体积是你不得不考虑的一部分. App安装包的巨细直接或间接地影响着下载转化率,安装时刻,磁盘空间等重要指标. 依据谷歌商店的内部数据,APK体积每削减10M,平均可添加1.6%的下载转化率. 换句话说, 你的App安装包每多6Mb, 你的用户添加就会削减1%. 而这个份额, 或许说App安装包的巨细, 在新式市场中受到的影响更大. 1
当然, 即便没有翔实的数据说明, 咱们也能明确的感受到App安装包的巨细对咱们运用的影响.
那么, 咱们又改怎么减缩咱们的App安装包巨细呢?
咱们先来看一下Google官方推荐的办法: Reduce your app size
首推的办法便是运用App Bundles, 而App Bundles的首要功用便是在运用安装时主动挑选对应分辨率下资源文件, 来到达最低成本削减运用巨细的意图.
而关于削减App安装包巨细的部分,咱们能够看到大部分的篇幅都是关于怎么通过处理资源文件来到达咱们的诉求.
咱们再来看一个App安装包巨细的剖析, 咱们能够看到一个10Mb左右的运用, 其资源文件能够到达6.1Mb.
尽管其间不全是图片资源, 可是图片资源再其间占比仍能到达九成以上. 那么紧缩图片资源便是一件性价比很高的工作了.这也就成为了咱们开始处理App安装包巨细的时分所做的第一步. 也是最显着的一步.
而Google也早就帮咱们在AndroidStudio集成了一个高性价比和简略快捷的东西WebP.Use WebP file format
每次运用WebP都是那么的简略和快捷. 不知道你有没有考虑过, WebP是怎么影响Android运用的巨细? 或许说WebP是怎么做到在不影响显现作用的前提下, 削减图片的巨细?
图片格局相关概念
在具体剖析WebP紧缩功用之前, 咱们需求了解一些根底的图片格局相关的概念. 以便协助咱们了解后续比较.
RGB/YUV/YCbCr
RGB
RGB是咱们通过模拟的三原色(红Red, 绿Green, 蓝Blue)而构成的(终究混合为白色). 标准的RGB形式为RGB24, 分别是8位R,8位G,8位B表明. 假如加上A(Alpha), 就构成了咱们在开发进程中常运用的颜色标识办法RGBA. 这个标准下共需求32(8*4)位来存储.
YUV
YUV则是通过电视的开展而不断改进构成的, 早起的电视都是以黑白为主,也便是说咱们只需求记载亮度Y(Luminance)即可. 而跟着彩色电视的开展, 单纯的亮度Y不足以满意彩色的需求, 所以变有了色度U(Chrominance)和浓度V(Chroma).
YCbCr
YCbCr是YUV的一种变种, 它是为数字视频转化而设计的非肯定颜色模型(肯定颜色模型是指不依赖任何外部因素就能够精确表明颜色的模型). 和YUV相同, Y表明的是亮度(Luminance), 而Cb代表的是RGB 输入信号蓝色部分与亮度之间的差值也叫蓝色色度(Chroma Blue), Cr代表的是赤色部分与亮度之间的差值也叫赤色色度(Chroma Red).
RGB/YUV/YCbCr实践别离作用
RGB2 | YUV3 | YCbCr4 |
---|---|---|
当然, 他们直接是能够互相转化的.RGb<->YCbCr: http://licheng.sakura.ne.jp/hatena6/rgbyc.html
索引色/ 直接色
索引色
索引色是通过一个索引表来表明颜色的. 也便是说, 咱们只能通过对应的索引来记载有限的颜色信息.
直接色
直接色则是通过直接记载颜色信息来表明颜色的. 也便是说, 咱们能够通过直接记载颜色信息来记载足量的颜色信息. 比方咱们常用的RGB24, 其便是直接色的一种.
位图/ 矢量图
位图
位图便是咱们常说的点阵图或许像素图. 简略来说, 构成位图的最小单位是像素, 假定咱们有一个10*10像素的位图, 那么咱们就有100个像素点的信息. 因为其特性, 位图在扩大的时分会呈现锯齿, 也便是咱们常说的马赛克.
矢量图
矢量图也被称为向量图. 矢量图是通过数学公式来描绘图画的. 也便是说, 矢量图是通过一系列的点来描绘图画的. 因为其特性, 矢量图在扩大的时分不会呈现锯齿. 可是矢量图也有其局限性, 因为其是通过数学公式来描绘图画的, 所以矢量图只能描绘一些简略的图形, 而不能描绘杂乱的图形.
咱们能够看到, 即便在高扩大的状况下, 矢量图仍可保证其显现作用.
有损/无损紧缩
无损紧缩
无损紧缩便是在紧缩的进程中, 不会丢掉任何信息. 也便是说, 无损紧缩的图画在解紧缩后和原图画是彻底共同的. 其紧缩的首要原理是相同的颜色信息只保存一次. 从本质上来说, 无损紧缩通过删去重复的内容的办法来到达紧缩图片巨细的意图. 可是当图片读取的时分, 软件又会把紧缩的数据(删去的重复内容)从头计算出来, 所以其占用的内存巨细和紧缩前的图片是共同的. 也因其特性, 所以不管你紧缩/解压多少次, 紧缩后的图片巨细解压后的显现作用都是不变的.
假定咱们有如下①的4*4像素的内容, 其间每个像素点的颜色都是不同的, 那么咱们就需求记载16个像素点的颜色信息. 我通过②③④,zig-zag序列化将其转化为⑤{1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3}, 也便是咱们的原始数据, 假如不紧缩那么咱们就需求记载这16位(不考虑标志符)的数据, 可是通过咱们的⑥无损紧缩的操作后, 咱们就得到了紧缩后的内容⑦(1, 6), (2, 4), (3, 6), 咱们只是需求记载6位(不考虑标记符号)的数据就能够了, 当然这儿咱们依然能够继续紧缩(比方哈夫曼编码, 不过这个就和图片自身无关了). 而①和⑦之间是能够无限次进行没有数据丢掉的转化.
有损紧缩
当咱们进行有损紧缩时, 咱们会主动删去一些信息.能够说, 有损紧缩的原理便是在不影响图片显现的前提下通过一定的算法丢掉一些信息 从本质上来说, 有损紧缩通过删去不重要内容的办法来到达紧缩图片巨细的意图.
这儿咱们简略介绍两方面的有损紧缩方向:
人眼对颜色的不灵敏, 对亮度灵敏
通过研究人员的许多实验, 证明了人类视觉体系对亮度的更灵敏, 而对颜色没那么灵敏. 咱们能够看到下图, 其间A的B两个区域的颜色相同的. 可是在第一张”亮度”不共同的状况下, 咱们很难看出其是相同的颜色.
也便是说, 咱们能够通过削减颜色的数量来到达紧缩图片巨细的意图.
假如你仍是不信任, 那么咱们来看一下下面这张图片, 你能看出来这张图片大部分的地方是灰白的么?5
通过扩大咱们能够看到, 仅有五分之一的部分是有颜色的, 其余的部分都是灰白的. 可是当我检查这个图片的时分, 咱们的大脑会主动的补全这些灰白的部分, 然后让咱们看到这张图片是彩色的.
当然在实践的运用傍边, 咱们不会这么极端的紧缩, 可是咱们是能够通过削减颜色的数量来到达紧缩图片巨细的意图.
人眼对高频信号不灵敏, 对低频信号灵敏
图画包括各种频率, 大部分为低频, 少部分为高频. 人眼对低频信号的灵敏度要高于高频信号. 也便是说, 咱们能够通过削减高频信号来到达紧缩图片巨细的意图.
这儿的话咱们以jpeg的DCT改换为例, 在不同频率的添加下, 对整体作用的影响.6
0 | 4 | 8 |
---|---|---|
16 | 32 | 60 |
---|---|---|
咱们能够看到, 当低频重量参加时, 图画的首要内容现已呈现了, 而高频重量的参加, 只是是让图画更加清晰. 乃至大部分高频重量的参加, 咱们都无法感知到.
常用图片格局紧缩原理
本文首要触及WebP的介绍, 故关于PNG,JPEG和GIF的紧缩原理只进行简略的介绍. 以便于对WebP原理比照了解.
GIF
GIF是一种无损, 索引色的的位图图形格局. 因为选用了无损紧缩, 相比陈旧的bmp格局, 尺寸较小, 而且支撑通明和动画. 可是因为gif只存储8位索引, 所以最多能表达2^8=256种颜色. 这儿话咱们就不过多介绍.
PNG
PNG是一种无损,直接色的位图图形格局.
紧缩原理简述
猜测编码
基本思路为增量编码, 核心的思路是任何数值都能够表明为先前值的差值.
假定咱们有如下内容:
咱们想要记载”x”的内容, 其间一种办法是通过A和B来取得, (X-((A+B)/2).
那么咱们就能够通过如下办法来记载后续内容:
当然, 这只是其间一种形式, PNG的算法提供了下面五种记载的办法
- 无过滤
- X与A的差异
- X与B的差异
- 平均值
- Paeth 猜测
大致的作用如下:
终究会依据不同的形式挑选最优的办法来记载.
这儿需求留意的是, PNG是针对每行挑选一种形式.
紧缩
后续的话会选用LZ77算法进行紧缩. 和GZip的紧缩原理相似, 通过记载重复的内容来到达紧缩的意图.
局部最优解不是大局最优解
咱们能够一下下图, 一个92* 270的图片比90* 270的图片大了将近一倍.
从逻辑上来说, 只是添加540个像素不应该让图片的巨细添加一倍.
上图中, 颜色越深则代表了紧缩份额越高, 咱们能够看到 因为添加了2像素, 使得PNG在每行中挑选的紧缩形式发生了变化, 即便每行的紧缩份额都提高了. 可是整体的紧缩份额却下降了.
JPEG紧缩原理简述
JPEG是一种有损,直接色的位图图形格局.
紧缩原理简述
JPEG的紧缩进程相关于来说要更加费事, 这儿咱们将其精简为两个首要进程.
假如你对其具体细节感兴趣, 能够拜访 The Unreasonable Effectiveness of JPEG: A Signal Processing Approach: https://www.youtube.com/watch?v=0me3guauqOU 来了解更多.
颜色空间转化和颜色下采样
这两个进程的成果是通过削减记载的颜色信息来到达紧缩的意图.
在前面咱们能够知道人眼体系关于颜色不灵敏, 关于亮度灵敏. 可是咱们常用的RGB24无法记载亮度的信息, 这时咱们就要将其转化为YCbCr, 然后记载包括亮度的信息.
在JPEG的紧缩算法中, 咱们会将每4个Cb或许Cr的数值(通常为左上)记载为一个数值, 然后到达削减颜色信息的意图. 也便是YCbCr420, 这儿不是说不记载Cr重量, 它指得是对每行扫描线来说, 只有一种色度重量以2:1的抽样率存储. 相邻的扫描行存储不同的色度重量, 也便是说,假如一行是4:2:0的话, 下一行便是4:0:2, 再下一行是4:2:0. 终究的作用便是每四个Y共用一组UV重量.
咱们截取一个8*8的图片内容. 并别离其YCbCr重量.
针对Cb重量咱们每四个像素点记载其左上点的内容.
直至彻底记载结束.
Yc的处理办法和Yb共同.
终究咱们将其合并并和原图比较.
咱们能够看到, 在不影响显现作用的前提下, 咱们削减了许多的颜色信息.
假如咱们之前的图片是RGB24的格局, 那么记载4个像素点的时分就需求记载12位的数据. 可是咱们通过颜色空间转化和颜色下采样的办法处理后, 咱们就只是需求记载6位数据就能够了. 单单这个处理就能够削减50%的图片颜色信息.当然, 作为价值, 咱们也丢掉了一部分的信息.
DCT改换及量化
DCT改换是一种依据余弦改换的离散改换, 通过将图画分解为一系列的余弦函数来到达紧缩的意图.
简略来说, 咱们能够将下面这个图形分解为一系列的余弦函数.
实践上能够分解为: cos(x)+cos(2x)+cos(4x)
咱们来看一个经典的比方7, 左边是终究图画. 中心是添加到终究图画的加权函数(乘以系数). 右边是当前函数和对应的系数.
假定咱们将某个图片转化为如下矩阵8:
咱们通过DCT改换后, 咱们就能够得到如下矩阵, 具体改换进程这儿就不多进行赘述了概况能够参阅文章JPEG codec example: Quantization:
咱们能够看到矩阵中呈现了许多易于紧缩的数据. 这儿易于紧缩的数字部分便是图片的高频部分, 也便是咱们人眼不灵敏的部分. 而咱们操控JPEG紧缩时的作用便是操控DCT改换的系数, 通过其影响咱们终究矩阵中0的数量. 当咱们矩阵中呈现许多的0的时分, 咱们的矩阵就能够紧缩更高的份额. 当然, 咱们高频的内容丢掉的就更多, 咱们看到的图片的质量就更差.
咱们再看一下这儿的比照, 当我的系数越大时, 咱们矩阵中0的数量就越少, 矩阵的紧缩比较就越小, 显现的作用就越好, 当咱们的系数越小时, 咱们矩阵中0的数量就越多, 矩阵的紧缩比就越大, 显现的作用就越差.
可是当咱们的系数为16的时分, 咱们就能不受影响的显现出原图的作用了. 因为系数的添加并非时线性的, 平等体量的低频数据比平等体量的高频数据带来的显现作用要好的多.
0 | 4 | 8 |
---|---|---|
16 | 32 | 60 |
---|---|---|
WebP紧缩原理
WebP是一种有损/无损,直接色的位图图形格局. 是在WebM的视频编码格局的根底上开展而来的. 尽管Android Studio提供的WebPConvert东西中不提供Gif格局的转化, 但实践上WebP是支撑Gif格局的转化的.
有损紧缩
关于WebP的有损紧缩, 咱们能够了解为PNG的依据猜测编码+JPEG的颜色转化和DCT改换.
颜色空间转化, 运用帧内猜测
和JPEG的颜色转化相似, WebP也对颜色空间进行转化, 可是WebP的颜色空间转化是依据YUV的.
WebP运用帧内猜测和PNG的猜测编码相似, 同样是通过图画已编码的一部分猜测另一部分的信息.不过在有损紧缩下WebP的运用帧内猜测运用的是VP89的帧内猜测, 而VP8则是依据块猜测10.
帧内猜测的第一步为分块, 值得提到的是, WebP的分块巨细并不是固定的, 他会跟着图片细节丰厚程度进行调整. 其首要分为4 *4, 16 *16以及8 *8的巨细, 如下图, 假如咱们有一个16 *16的区域, 依据图片中实践内容的不同, 咱们会采纳不同的分块巨细.
由此带来的优点是, 咱们能够依据图片的内容来挑选最优的分块巨细, 然后到达更好的紧缩作用. 咱们能够看一张实践图片的分块示例:
咱们能够看到, 在图片细节不丰厚的部分, 咱们选用了16 *16的分块, 而在图片细节丰厚的部分, 咱们选用了4 *4的分块.
帧内猜测的第二步则为猜测, 咱们在一个分块中, 通过现已编码的部分来猜测未编码的部分. 然后到达削减记载内容的意图.
前面咱们现已将图片信息转化为YUV的格局进行存储, 尽管有三个重量, 可是咱们一般将其划分为Y(luma)和UV(Chroma)两种状况进行处理.
在不同的luma分块巨细下, 咱们采纳的猜测办法也有所不同.
- 4 *4分块 因为4 *4分块处理的是细节丰厚的部分, 所以共有九种猜测办法:
其作用如下:
原图 | 猜测作用 |
---|---|
- 16 *16分块 因为16 *16分块处理的是细节不丰厚的部分, 所以就只有四种猜测办法:
原图 | 猜测作用 |
---|---|
- 8 *8分块 8 *8分块比较特别, 仅在高质量(High profiles)形式下收效. 和4 *4分块相似, 8 *8分块有有着相同的九种猜测办法.
上述的的分块及猜测办法只是是针对Y(luma)重量的, 而UV(Chroma)重量会跟着Y重量的分块的生成而生成, 不过不管UV(Chroma)重量分块的巨细怎么, 都是只有和16 *16分块相似的四种猜测办法(具体完成进程共同, 可是编号不共同).
当然, 咱们测验猜测不同形式的作用后, 咱们会找到最佳的猜测形式. 并将其带入一个进程.
DCT改换及量化
WebP的DCT改换及量化和JPEG的DCT改换及量化基本共同, 可是WebP的DCT改换及量化是依据VP8块猜测后残值的处理, 而JPEG的DCT改换及量化是依据颜色空间转化后的处理. 简略来说JPEG处理的是原值, 而WebP处理的是原值修改过的残值. 具体的内容能够参阅前面JPEG的DCT改换及量化部分, 首要的思路便是通过DCT改换将原值转化为一系列的余弦函数, 再依据人眼对高频信息的不灵敏, 通过量化将高频信息削减, 然后到达紧缩的意图. 这儿就不在过多的赘述了
当然, 后续的操作也不是彻底的共同, 比方WebP选用的是管用熵编码, 而不是霍夫曼编码. 可是这些都是细节的问题, 不影响咱们对WebP的了解.
具体的流程能够参阅下图:
这儿咱们无妨考虑以下, 为什么会说WebP的有损紧缩比JPEG的更好呢?
- 猜测编码, 通过猜测编码, 咱们能够削减重复的信息, 然后到达紧缩的意图.
- 块的自适应挑选, 通过自适应挑选, 咱们能够依据图片的内容来挑选最优的分块巨细, 然后到达更好的紧缩作用.
- 量化, 通过量化, 咱们能够削减高频信息, 然后到达紧缩的意图. 可是因为两者君运用的是DCT的改换, 所以其应该作用是共同的.
- 管用熵编码, 和霍夫曼编码相比, 管用熵编码大概能够节省5%-10%的空间.
无损紧缩
WEBP的无损仍是依据猜测编码和削减空间冗余性的.
猜测编码
WEBP的无损紧缩状况下的猜测编码和PNG的猜测编码基本共同, 可是其猜测编码的形式更多, 具体的形式能够参阅下图, 下面咱们猜测P的内容11:
咱们共有14种不同的猜测办法
.
通过处理后, 咱们就得到了一个可逆的差值, 而差值相关于原值, 内容更少. 更有利于咱们的紧缩.
颜色转化,减Green转化及颜色索引转化
颜色转化的方针是去除多余的颜色记载, 在进行颜色转化的时分, 咱们会保留绿色(G)的值, 然后依据绿色转化为赤色(R), 通过绿色或赤色的来转化蓝色(B).
需求留意的是, 这个操作是需求分块的, 针对每一块挑选上述三种转化办法的某一种.
随后咱们会进行减Green转化, 简略来说, 咱们将绿色值的内容添加到赤色和蓝色中. 然后到达削减颜色记载的意图.
假如像素值不是许多, 运用创立颜色索引数组并通过该数组的索引替换像素值或许更有用.颜色索引改换完成了这一点.颜色索引改换检查图画中仅有的ARGB值的数量.假如该数量低于一个阈值(256), 它将创立一个包括这些ARGB值的数组, 然后用相应的索引替换像素值.
紧缩
WebP的紧缩办法并不是仅有的, 除了前面提及的霍夫曼编码, 还有LZ77后引用编码, 以及颜色缓存编码.
常见图片格局作用比照
在有损紧缩的状况下, 只是考虑紧缩比的话, WebP的文件巨细要比JPEG的文件巨细少26%. 这儿就不做具体比照, 直接检查定论, 假如想看具体的比照进程的话, 能够拜访:WebP Compression Study进行检查.
这儿需求留意的是无损紧缩的状况, 假如咱们需求紧缩一张带有许多文字的图片, 或许得到一个反直觉的成果:
图片 | Size | |
---|---|---|
原图 | 2200k | |
PNG | 150k | |
WebP无损 | 52k | |
WebP有损(100质量) | 165K |
咱们能够看到, 在这样的图片下, WebP的有损紧缩比无损紧缩的巨细还要大. 原因也很简略, 这样的图片有着许多重复的信息, 这些信息在有损紧缩下会被紧缩的很高, 而无损紧缩是依据猜测编码的, 即便有着许多重复的信息, 仍要记载下来, 所以无损紧缩的巨细会比有损紧缩的大.
图片紧缩运用的东西为:squoosh.app/
总结
WebP紧缩份额高并不是没有价值的, 一般的状况下, WebP编码的时刻耗费的时刻比JPEG要高10倍, 解码的时刻耗费仍高一半. 可是考虑到WebP文件的巨细, 整体耗费的时刻反而会更少.
行文至此, 信任对现在对图片紧缩算法都有了一定的了解. 只要在减缩Apk资源的时分不会一股脑的挑选将所以图片都转化成WebP, 而且还对GIF的图片视而不见, 那么就现已到达了本文的意图.
Footnotes
-
medium.com/googleplayd… ↩
-
en.wikipedia.org/wiki/RGB_co… ↩
-
en.wikipedia.org/wiki/Y%E2%8… ↩
-
zh.wikipedia.org/wiki/YCbCr ↩
-
twitter.com/hodefoting/… ↩
-
www.youtube.com/watch?v=0me… ↩
-
en.wikipedia.org/wiki/Discre… ↩
-
en.wikipedia.org/wiki/JPEG#Q… ↩
-
en.wikipedia.org/wiki/VP8 ↩
-
static.googleusercontent.com/media/resea… ↩
-
datatracker.ietf.org/doc/draft-z… ↩