文章连接html
通过多个版本迭代,项目在release
配置下的打包体积依旧轻松破百,应用体积过大致使的问题包括:python
加班
TEXT
段体积过大会致使审核失败一般来讲,资源文件能在应用体积包中占据1/3
或者更多的体积,相比起代码(5kb/千行)
的平均占用来讲,对图片进行减包是最直接高效的手段,对图片资源的处理方式包括四种:算法
考虑到因为项目开发分工的问题,方式1
须要推进落地,因此本文不讨论这种处理方式。其余三种都能经过编写脚本实现自动化处理数组
图片压缩分为有损压缩
和无损压缩
两类,有损压缩
放弃了一部分图片的质量换取更高的压缩比。网上主流的压缩工具备tinypng
、pngquant
、ImageAlpha
和ImageOptim
等,分别采用了一种或者多种压缩技术完成图片压缩app
因为png
格式的灵活性,同一张图片可使用多种方式进行表示,不一样方式占用的大小不同。通常的软件会采用效率更高的方式来表示图片,因此这种状况下png
图片存在巨大的优化空间。一般来讲,从png
文件中能去除的数据包括:工具
iTXt
、tEXt
和zTXt
这些能够存储任意文本的数据区段iCCP
数据区段存储的profile
等等photoshop
导出的png
图片存在大量的额外信息png
图片有两种类型的数据块,一种是必不可缺的数据块称为关键数据块
。另外一种叫作辅助数据块
,png
文件格式规范指定的辅助数据块包括:测试
bKGD
cHRM
γ
数据块gAMA
hIST
pHYs
sBIT
tEXt
tIME
tRNS
zTXt
其中tEXt
和zTXt
数据段中存在的数据包括:优化
关键字 | |
---|---|
Title | 图像名称 |
Author | 图像做者 |
Description | 图像说明 |
Copyright | 版权声明 |
CreationTime | 原图创做时间 |
Software | 创做图像使用的软件 |
Disclaimer | 弃权 |
Warning | 图像内容警告 |
Source | 创做图像使用的设备 |
Comment | 注释信息 |
由上可见,辅助数据块在png
文件中可能占据了极大的篇幅,正是这些数据块构成了png
的无损压缩条件spa
tinypng
采用了一种称做Quantization
的压缩技术,经过合并图片中类似的颜色,将24bit
的图片文件压缩成8bit
图片,同时去除图片中没必要要的元数据,图片最高能达到70%
以上的压缩率。截止文章完成以前,tinypng
仅提供了线上压缩功能,暂未提供工具下载命令行
根据官方介绍,pngquant
将24bit
以上的图片转换成8bit
的保留透明度通道的压缩图片,压缩算法的压缩比很是显著,一般都能减小70%
的大小。pngquant
提供了命令行工具来完成解压任务:
pngquant --quality=0-100 imagepath
复制代码
命令行更多调试参数能够在官网参阅
ImageAlpha
是一个macOS
系统下的有损图片压缩工具,内置了pngquant
、pngnq-s9
等多个压缩工具,多数状况下经过将图片降至8bit
来获取高压缩比。因为ImageAlpha
的可视化界面没法批量处理图片,直接使用提供的命令工具能够实现批量压缩图片:
for file in $(ls $1); do
imagepath=$1"/"$file
if [ -d imagepath ]
then
/// 路径为文件夹
else
if [[ $file == *.png ]]
then
beforeSize=`ls -l $imagepath | awk '{print $5}'`
/Applications/ImageAlpha.app/Contents/MacOS/pngquant $imagepath
afterSize=`ls -l ${imagepath/.png/-fs8.png} | awk '{print $5}'`
if [[ $afterSize -lt $beforeSize]]
then
mv ${imagepath/.png/-fs8.png} $imagepath
fi
fi
fi
done
复制代码
使用ImageAlpha
须要注意两点:
-fs8
后缀,须要使用mv
命令实现替换关键数据块
,可能致使压缩图片尺寸增大,须要过滤在使用有损压缩
时须要注意单张png
图片是能够被屡次压缩的,但这会致使图片的清晰度和色彩都受到影响,不建议对图片超过一次以上的有损压缩
ImageOptim
是介绍的四种工具中惟一的无损压缩
,它采用了包括去除exif信息
、从新排列像素存储方式
等手段实现图片的压缩。无损
表明着一张图片被ImageOptim
压缩后,后续没法再次进行压缩,同时它的压缩比每每比不上其余的有损压缩
方案,但最大程度上保证了图片的原始清晰度和色彩
for file in $(ls $1); do
imagepath=$1"/"$file
if [ -d imagepath ]
then
/// 路径为文件夹
else
if [[ $file == *.png ]]
then
/Applications/ImageOptim.app/Contents/MacOS/ImageOptim $imagepath
fi
fi
done
复制代码
ImageOptim
一样存在可视化的工具而且支持批量压缩图片
考虑到ImageAlpha
几乎都是使用pngquant
做为压缩工具,所以只列出三种压缩工具的对比:
原始尺寸 | 压缩工具 | 压缩后尺寸 | 压缩比 |
---|---|---|---|
319.5KB | tinypng | 120.5KB | 62% |
319.5KB | ImageAlpha-pngquant | 395KB | -24% |
319.5KB | ImageOptim | 252KB | 21% |
测试图片采用qq
聊天截图生成的png
,tinypng
压缩率很是高,而pngquant
的表现不尽人意
一般来讲,出现重复图片的缘由包括模块间需求开发没有打通
或是缺乏统一的图片命名规范
。经过图片MD5
摘要是识别重复图片的最快方法,以python
为例,匹配重复图片的代码以下:
md5list = {}
for file in files:
if os.path.isdir(file.path):
continue
md5obj = hashlib.md5()
fd = open(file.path, 'rb')
while True:
buff = fd.read(2048)
if not buff:
break
md5obj.update(buff)
fd.close()
filemd5 = str(md5obj.hexdigest()).lower()
if filemd5 in md5list:
md5list[filemd5].add(file.path)
else:
md5list[filemd5] = set([file.path])
for key in md5list:
list = md5list[key]
if len(list) > 1:
print (list)
复制代码
在遍历中以文件MD5
字符串做为key
,维护具有相同MD5
的图片路径,最后遍历这个map
查找存在一个以上路径的数组而且输出
类似图片在图片内容、色彩上都十分的接近,多数时间能够考虑复用这些图片,但类似图片的问题在于没法经过MD5
直接匹配。为了确认两个图片是否类似,要使用简单的一个数学公式来帮忙查找:
方差。在几率论和统计学中,一个随机变量的方差描述的是它的离散程度,也就是该变量离其指望值的距离
举个例子,甲同窗五次成绩分别是65, 69, 81, 89, 96
,乙同窗五次成绩是82, 80, 77, 81, 80
,两我的平均成绩都是80
,可是引入方差公式计算:
甲: ((65-80)^2 + (69-80)^2 + (81-80)^2 + (89-80)^2 + (96-80)^2) / 5 = 136.8
乙: ((82-80)^2 + (80-80)^2 + (77-80)^2 + (81-80)^2 + (80-80)^2) / 5 = 2.8
复制代码
平均值相同的状况下,方差越大,说明数据偏离指望值的状况越严重。方差越接近的两个随机变量,他们的变化就越加趋同,获取方差代码以下:
def getVariance(nums):
variance = 0
average = sum(nums) / len(nums)
for num in nums:
variance += (num - average) * (num - average) / len(nums)
return variance
复制代码
所以将图片划分红连串的一维数据,以此计算出图片的方差,经过方差匹配能够实现一个简单的图片类似度判断工具,实现前还要注意两点:
RGB
色彩值会致使方差的计算变得复杂,因此转成灰度图能够下降难度最终将图片转换成一维数据列表的代码以下:
def getAverageList(img):
commonlength = 30
img = cv2.resize(img, (commonlength, commonlength), interpolation=cv2.INTER_CUBIC)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
res = []
for idx in range(commonlength):
average = sum(gray[idx]) / len(gray[idx])
res.append(average)
复制代码
将图片转成灰度图后,仍然可能存在RGB
色值不一样但灰度值相同的状况致使判断失准,能够考虑两种方案提升算法的检测准确率:
列平均像素值
为单位的一维列表计算另外一个方差,两个方差值一并作判断R
、G
、B
三种色彩平均值的一维列表,计算出三个方差进行匹配检测通过两轮图片减包处理后,整个项目资源产生的减包量约有20M
,其中经过文中的三种手段产生的减包量在6.5M
左右,总体上来看产出仍是比较可观的