使用 python 壓縮 png 圖片,高達 80% 壓縮率,肉眼無差異(二):使用 pngquant 實現圖片壓縮


在網上有很多使用 python 的 pillow 庫進行圖片壓縮的教程,使用簡單,但是壓縮效果存在明顯的色彩不自然,這是因為 pillow 庫采取的壓縮算法沒有優化的問題。

這個系列實現一款簡單的壓縮工具,使用 pngquant 有損壓縮,壓縮率高達 80%, 而且壓縮后的圖片沒有明顯差異。

系列文章:

1,使用 python 壓縮 png 圖片,高達 80% 壓縮率,肉眼無差異(一):為什么不用 pillow庫.md

2,使用 python 壓縮 png 圖片,高達 80% 壓縮率,肉眼無差異(二):使用 pngquant 實現圖片壓縮

3,使用 python 壓縮 png 圖片,高達 80% 壓縮率,肉眼無差異(三):使用 click 庫實現命令行

4,使用 python 壓縮 png 圖片,高達 80% 壓縮率,肉眼無差異(四):使用 requests 庫上傳

上一篇我嘗試使用了 pillow 庫對 png 圖片進行了壓縮,效果不好。這次我換用 pngquant 來壓縮。 pngquant 是用於 PNG 圖像有損壓縮的命令行實用程序和庫。壓縮程序會顯著減小文件大小(通常高達70%),並保持完全的alpha透明度。通過使用alpha通道將圖像轉換為更高效的8位PNG格式(通常比24/32位PNG文件小60-80%)。

pngquant 使用的算法主要是中值切割量化算法的改進版和 K-means 顏色校正。得到的圖片顏色差異肉眼幾乎無法察覺。

這是 pngquant 優化后的圖片,幾乎看不出區別: pngquant effect.jpg

這是 pillow 同樣采用中值切割和 k-means 得到的優化效果, 雲彩有明顯顏色過渡不自然問題: quantize effect.jpg

pngquant 壓縮庫安裝

pngquant 提供了源碼、命令行和 GUI 等多種形式。它不是 python 寫的,所以只能用 python 調用命令行或者源碼函數。 GUI 的工具目前來說還比較難用,並沒有命令行方便,而源碼形式可以通過 ctype 使用 python語言去調用 c 源碼。但是目前對這方面還不怎么了解,可以后面再去使用 so 動態庫等方式。

先用命令行形式進行 PNG 壓縮。

1,下載 windows安裝包 或者 mac 和 linux 版本的安裝包。

2,命令行輸入 pngquant 就可以使用了;

3,為了使用方便,可以配置環境變量(后面如果和 picom 集成在了一起再去掉 )。

pngquant-fs8.pngpngquant-fs8.png

快速使用 pngquant

pngquant 圖片名稱.png

對於一些可選參數的說明:

1,--skip-if-larger pngquant 有時候壓縮的文件會比源文件大。這個選項會判斷,如果大就取消執行。強烈建議加上

2,--quality 0-100 圖片質量。對於顏色沒有特別要求的可以縮減到 10, 但是越小壓縮率越低,通常不需要設置。

3,--force 強制執行,pngquant 會判斷,如果有一個已經壓縮的同名文件在當前文件夾,就不會執行。這個選項會覆蓋原來的文件。

4,--output file 指定輸入文件的名稱。 可以指定為 jpg 格式,但是圖片不會變得更小。

5,--speed 執行速度

使用 subprocess 調用 pngquant 命令行

對應的程序:

import subprocess
subprocess.run('pngquant elephant.png')

如果想獲取程序運行時屏幕上顯示的內容,可以使用 check_output 方法,在這里不需要。

接下來使用 subprocess 封裝對應的壓縮函數:

def pngquant_compress(fp, force=False, quality=None):
    """壓縮函數.
    
    參數:
        fp: 文件名稱
        force: 如果存在同名文件,是否覆蓋
        quality: 壓縮質量。 10-40, or 10
    """

    force_command = '-f' if force else ''
    
    quality_command = ''
    if quality and isinstance(quality, int):
        quality_command = f'--quality {quality}'
    if quality and isinstance(quality, str):
        quality_command = f'--quality {quality}'
    
    command = f'pngquant {fp} --skip-if-larger {force_command} {quality_command}'
    subprocess.run(command)


if __name__ == "__main__":
    pngquant_compress('elephant.png', force=True, quality=20)

總結

之前使用大多數教程推薦的 pillow 庫,效果並不好。這次換用知名的 pngquant 以后,色彩已經用肉眼很難感知。 要實現對 png 圖片的壓縮率和圖片效果的平衡,pngquant 真是個不錯的工具。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM