文章連接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
左右,總體上來看產出仍是比較可觀的