- Published on
實測 PIL 壓縮圖片(WebP、Jpeg)之差異
- Authors
- Name
- Wen Chen
前言
繼上一篇寫了:用python批次將圖片轉檔成webp並壓縮 後,寫完的當下突然想到,當初單純想試試用WebP
作為 Blog 主要的圖片格式,實際上卻沒有實際測試過 JPG 與 WebP 壓縮過後的差異,於是便產生了這篇文章。
這篇主要還是會透過上次寫出來的程式碼,使用 Pillow 做轉檔,裡面只會最簡單的對 quality
做設定,其他都保持 default ,來粗糙測試兩者壓縮出來檔案的差異。
WebP 是啥?
先提提什麼是 WebP , 底下擷取幾段從維基百科獲取的內容:
WebP最初在2010年9月釋出,其支援庫於2018年4月發布1.0版本。截至2021年5月,已有94%的瀏覽器支援此格式。
WebP的無失真壓縮比網路上找到的PNG檔少了45%的檔案大小,即使這些PNG檔在使用pngcrush和PNGOUT處理過,WebP還是可以減少28%的檔案大小。
維基百科內只有提到無損壓縮,可以比 PNG 減少 45% 的檔案大小,然而有損壓縮部分,透過在網路上查到的數據,大概可以比 jpg 減少 20% 左右的檔案大小。
無損壓縮? 有損壓縮?
提一下兩者差異,畢竟本篇主要還是實測。
- 有損壓縮:犧牲部分信息來壓縮圖片,壓縮後不可逆 (JPG),每次壓縮會越壓畫質越差。
- 無損壓縮:壓縮後不影響圖片品質 (PNG),如果有頻繁更動照片的需求,使用 PNG。
再來說說我自己的使用情境,我的照片調整完不會有頻繁更動的需求,所以基本上都是有損壓縮,且雖然有損壓縮聽起來可怕,但從各裝置上來看,除非真的放大比較,不然肉眼上根本看不出差異。
實測
無損壓縮
因為在離開影視產業後,我拍照幾乎都直接拍 jpg 檔,因為已經經過一次相機壓縮,所以主要測試對照,我上 Signature Edits 找了免費的 Raw 檔透過 LR 直出成 PNG 做測試。
先上程式碼:
import glob
from PIL import Image
png = glob.glob('./raw/*.[pP][nN][gG]')
for i in png:
print(i)
im = Image.open(i)
name = i.lower().split('/')[::-1][0]
webp = name.replace('png', 'webp')
# png => WebP
im.save(f'./converted/{webp}', "WebP", lossless=True)
# png => png
im.save(f'./converted/{name}')
基本上就是從原本的程式碼修改一下,WebP
存檔時加入 lossless=True
來無損壓縮,png 則是直接再存成 png 一次,其他均為 default。
我們先看下結果:
- 原圖透過 Lr 直出 PNG 檔案大小為 28.6MB
- Pillow 轉存成 PNG 檔案大小為 32MB
- Pillow 轉存成 WebP 檔案大小為 19.9MB
Pillow 轉存成 Png 檔案還比原始圖大,原因來自於 Lr 跟 Pillow 本身 default 設定還是有差異,不過就還是比較給各位參考。
也就得到了以下結果:
- WebP 無損壓縮對比原始 PNG 約減少了 30.4%
- WebP 無損壓縮對比同用 Pillow 轉存成 PNG 的檔案約減少了 37.8%
總體來說算是接近維基百科上的數據了。
有損壓縮
接著回到有損壓縮,也是我個人會使用的情境,這次會各轉成 Jpeg 與 有損 WebP 各一張,我們一樣先跑一次 default 看看結果:
程式碼:
import glob
from PIL import Image
png = glob.glob('./raw/*.[pP][nN][gG]')
for i in png:
print(i)
im = Image.open(i)
name = i.lower().split('/')[::-1][0]
webp = name.replace('png', 'webp')
jpg = name.replace('png', 'jpg')
# png => WebP
im.save(f'./converted/{webp}')
# png => jpg
im.save(f'./converted/{jpg}')
結果如下:
這次的差異就比較明顯了:
- JPG: 1.9MB
- WebP: 956kb
減少了將近 50% 的大小,當然,我相信並不是所有圖片壓縮後都能有這樣子的效果,不過 WebP
壓縮相較於 Jpeg
會比較小這件事是可以確定的!
最後放一張三者對比圖,在不特別標記的情況下,不曉得各位認為差距大不大呢? (這張圖截圖已經壓縮過)
文章最後會有 Google 雲端連結,保留所有原圖
我個人覺得,在預設參數下,放大非常多倍數的情況下,Jpeg
版本保留的細節比較多,但換個角度想:
假如加入 options
強制把 Jpeg
壓到 956 kb 左右,那畫質上 WebP
便會取勝。
實際情境
剛剛上面的測試是透過 Raw File 直出成 PNG 去轉檔的,那實際情境呢?
前面提到過,我個人拍照時相機都是拍 JPG 直出,本身已經經過一次相機壓縮,但對於我期望的檔案大小還是過大,所以在調整完色調後,我會再壓縮一次轉成 WebP
,期望每張圖片大小可以壓在 500kb 以下。
於是我找了一張之前拍的照片,原始大小為 1.8MB 的 JPEG:
前一篇文有提到我的 quality
大概都設在 40 ~ 50 之間,這參數是我針對我相機拍出來的照片,可接受的畫質範圍,檔案大幅瘦身,畫質也不至於太差。
某些文件顯示,設在 75~80 可以取得較好的容量畫質平衡
這次我先將我的 quality
設在 50,轉存一次 WebP :
im.save(f'./converted/{webp}', quality=50)
壓縮過後的WebP檔案大小為 465Kb
基於此標準經過幾次測試,要達到接近的大小水平,Jpeg 檔必須把 quality
設在 15 左右,而此時產出的Jpeg 檔案大小為 479Kb
# raw 為 jpg file
im.save(f'./converted/{raw}', quality=15)
假如同樣設在 quality=50 的話 Jpeg 的大小為 1.2MB
就如同先前推測的一般,當 Jpeg 的檔案壓縮至與 WebP 相同時,畫質會有明顯的差距,且是肉眼即可看出的差距,接著我們來看下差異:
透過大圖,我們其實就可以看出,Jpeg 的版本已經開始有點模糊,白色的部分也開始失真。
接著我們放大白色的部分,而放大後就更明顯了:
結論
從實測結果來看,確實 WebP
在壓縮過後,可以得到更小的容量,且在最後的實測,從 1.8MB 的 Jpeg 壓縮至 465Kb 的 WebP 後,再不特別放大的情況下,肉眼幾乎無法辨別差異。
總結來說,這次的實測一部分也算是驗證網路上提到那些優點,下次在專案中不妨試著嘗試使用 WebP
哦!
(放心,連結是google drive 沒有毒)