pngquantでPNG画像を圧縮

/ WEB

pngquantはpng画像を最適化してファイル容量を削減するオフラインで実行できるコマンドラインツールで、macOS/Windows/Linux全てのプラットフォームから利用できる。有料のWeb APIや無駄に重い無料のウェブサービスを使わなくても現状で最高品質の圧縮がローカルで高速に行えるためウェブ用のpng画像を圧縮するのに最適だ。

https://pngquant.org/

ウェブページhttps://pngquant.orgのスクリーンショット

GUIもあるようだが頑張ってでもコマンドライン版を使ったほうが良い。Binary for Windowsにはドラッグ&ドロップだけで圧縮できるバッチファイルも用意されている(実質GUI)。

pngquantのダウンロード

上記HPのDownloadの項目から各プラットフォーム用のモノをダウンロードできる。

  • Windows : Binary for Windowsからzipをダウンロードして好きな場所に展開するだけ。
  • macOS : Binary for macOSの項目はあるがbrew install pngquantするのが早い。
  • Linux : ソースコードを落として./configuremakeでバイナリを得る。yumapt-getなどのパッケージ管理があるなら一度sudo xxx install pngquantを試すとよい。

Linux版のビルドについて

https://pngquant.org/install.html

git clone --recursive https://github.com/kornelski/pngquant.git
cd pngquant
./configure
make

で済めば問題ない。オプションとしてsudo make installするとどこからでも使える。libpngが無いと./configureの段階で問題があると怒られるのでパッケージ管理システムがあるならinstall libpnginstall libpng-devなどでインストールしておく。もしパッケージ管理システムにアクセスできなくても(sudo権限が無くても)問題ない。

http://www.libpng.org/pub/png/libpng.htmlからlibpngのソースコードをダウンロードし、上記の文脈におけるpngquant以下に配置、そこで

tar zxvf libpng-1.6.37.tar.gz
cd libpng-1.6.37
./configure --enable-static
make

を行う。もとのpngquant以下に戻って./configureからmakeすれば勝手にstaticなlibpngを見つけてくれて通る。当然gccなどのコンパイラは必要なので無理な場合はバイナリを入手してくるしかない。

pngquantの使い方

pngquantと引数なしで起動するとヘルプが表示される。

普通に圧縮して上書きする

pngquant --ext .png --force 256 filename.png

デフォルトでは末尾が-fs8.pngまたは-or8.pngのファイルに結果が出力されるのでオプションで同名ファイルの上書きに指定している。

デフォルトの動作がよいならオプションを外せばよい。--outputで出力ファイル名を直接指定することもできるし--extで末尾だけ指定することもできる。末尾を.pngにする場合だけは同名ファイルになるので--forceで上書きさせる必要がある。以降はわかりやすさのため省略する。

最大限の最適化

pngquant -s1 256 filename.png

256は色の数のことを示しており、その色数のなかで元の画像を最も良く表現するカラーテーブルのパターンを探索する。-s1オプションでそのパターンを全探索させるように指定できる。静的かつ少数のファイルを圧縮する場合など、実行時間を気にする必要が無いなら指定しても良い。

デフォルトの値はヘルプとホームページで食い違っているが-s4-s3だそう。デフォルトのままで得られるパータンでも5%ほどしか(公式が言うところの)品質は落ちない。

クオリティで色数を指定

pngquant --quality=50-80 filename.png 

さきほどの256という色の数を変換元の画像に含まれている色数に対するパーセンテージでざっくり指定することができる。50-80なら最小値50%で最大値80%を表す。注意点として、変換結果が最小値で指定した色数を下回ると結果が出力されず元画像と同じ内容が出力される。この場合プロセスはエラーコード99で終了する。

最小値は指定しないのが簡単。

そのほか--skip-if-largerで元画像よりもサイズが大きい場合は出力をスキップする(既に最適化済のファイルを入力した場合にこの可能性がある、最適化してない画像に対してはほぼありえない)、--stripで不要なメタデータを削除するなどがある。--stripはmacOSではデフォルトらしい(なぜmacだけ?)。

Windowsのバッチファイルを用いる方法

Binary of Windowsにはエクスプローラからファイルをドラッグ&ドロップで圧縮できる。

pngquantのWindows用バッチファイル

赤枠の2つにファイルをドラッグアンドドロップで落とすと元ファイルの場所に-fs8.png-or8.pngの末尾のファイルで最適化済のものが生成される。複数ファイルも可能。ただし末尾がうっとおしい場合はこの方法だとこれ以上何もできないのでおとなしくコマンドラインを使ったほうが良い。

再帰的に配下のファイルを全て最適化する方法

フォルダの深さがわかっているなら以下でよい。

pngquant --ext .png --force 256 */*.png */*/*.png ...

これでとにかく全部最適化。

Linux系の場合は以下も使える。

find . -name '*.png' -exec pngquant --ext .png --force 256 {} \;

加えてマルチプロセスでやる場合のコマンドも以下に載せられているので大量のファイルを処理する場合には参考になる。

https://stackoverflow.com/questions/9647920/recursively-batch-process-files-with-pngquant/9649214#9649214

pngメモ

lossyとある通りこれは無損失の圧縮ツールではない。あくまで画像の見え方を保ちつつカラーテーブルを最適化することによってファイル容量を圧縮する。最適化の問題的に簡単なファイルでは理論上の見え方が変わらなくともファイル容量が減る場合もありえるので簡単なファイルは恩恵を受けやすいだろう。Algorithmの項に何をしているのかが具体的に書かれている。

ぼやき 冒頭で述べた有料のWeb APIや無駄に重い無料のウェブサービスは一体どういう所でこういうツールとの差別化を図っているのかが全く不明。サーバローカルでpngquantや他のフォーマットでも類似のものが使えるならそういうやつ必要なのか?あと無駄に重い無料のウェブサービス使うならpngquantのd&dでやる方がよほどいい。