mattintosh note

どこかのエンジニアモドキの備忘録

TwitterにPNGをアップするときにJPEGに変換されない画像を作る

2019年2月11日より TwitterPNG イメージをアップロードすると場合によっては JPEG イメージに変換されてしまうようになった(公式アナウンス)。いままであまり気にしてなかったのだけど久しぶりに macOS を使っていてスクリーンショットをダイレクトにアップロードする際に気になるようになってしまった。

PNG のままアップロードしたいという場合は色数の少ない PNG8 に変換したり長辺のサイズを 900 px 以下にしなければならない。できるだけ綺麗な見た目で解像度を変えずに PNG32 や PNG24 から PNG8 に変換するために pngquant というプログラムを使う。pngquant はコマンドで使うプログラムだが macOS の場合は Automator を使うことで Finder 上で PNG8 イメージに変換可能なアプリケーションを作成することができるし、Linux はアプリケーションファイルを作成すればいいだけなので結構簡単に GUI からも使える。pngquant を通すことでファイルサイズが 1/2 〜 1/4 くらいになるのでそこまで過度に綺麗さを求めないイメージのファイルサイズを削減できる(これは1カ月の利用制限がある Hatena Fotolife を使っているユーザとしても有り難い)。

下記は実際に pngquant を使って Twitter にアップロードした画像。多少ザラつきはあるものの十分実用範囲。

Linux については語る必要はないと思うのでここでは macOS での話をする。

pngquant を用意する

pngquant 公式サイトから macOS の向けのバイナリをダウンロードする。

pngquant.tar.bz2 を解凍して扱いやすい場所に移動する。(例えば自分のホームディレクトリにある Applications ディレクトリなど)

パッケージマネージャを使っている場合はそちらからでも導入可能だが、MacPorts の方はバージョンが少し古い。

パッケージマネージャごとの pngquant バージョン(2019年10月23日時点)

パッケージマネージャ pngquant バージョン インストールコマンド
Homebrew2.12.5 (July 2019)brew install pngquant
MacPorts2.12.2 (January 2018)sudo port install pngquant

"PNG8 変換クイックアクション" の作り方

Automator を起動したらクイックアクションを新規作成する。クイックアクションは Finder などのアプリケーションで右クリックして表示したコンテキストメニューから作成した処理を実行させられるというもの。

編集画面が開いたら左の「ユーティリティ」メニューから「シェルスクリプトを実行」アクションをワークフローにドラッグするなりして追加する。設定のポイントは以下の部分。

  • ワークフローが受け取る現在の項目を「ファイルまたはフォルダ」に設定
  • 検索対象を「Finder.app」に設定
  • シェルスクリプトを実行」アクションの入力の引き渡し方法を「引数として」に設定

f:id:mattintosh4:20191023143907p:plain
Automator - シェルスクリプトを実行

以下の例では pngquant を ~/Applications/pngquant/pngquat に配置しているがそこは環境に合わせて変更すること。Automator では Finder.app の項目をファイルに限定することができないのでシェルの内部で弾くようにしておく(ディレクトリが渡されたら中身まとめて渡す、という処理を使いすることもできるがここではやらない)。pngquant のオプションはお好みで。

Automator - シェルスクリプトを実行 スクリプト

for f
do
    test -f "${f}" || continue
    ~/Applications/pngquant/pngquant --force --speed 1 256 "${f}"
done

テストでは 219 KB のファイルが 66 KB まで縮小した。

作成したアクションは Finder でファイルを単一または複数選択して右クリックのコンテキストメニューから 「クイックアクション」を開くと実行できる。

f:id:mattintosh4:20191023154512p:plain
Finder - クイックアクション

"グレースケール PNG8 変換クイックアクション" の作り方

漫画やイラストなどをグレースケール化して PNG8 にしたい場合。pngquant にはグレースケール化のオプションが無いので ImageMagick を使う。pngquant はパイプでデータを受け取ることができるので一時ファイルは不要。グレースケール化に特定のチャネルを使いたい場合などは -channel-separate などを併用する。接尾辞はカラーとの差別化のため -fs8g.png になるようにしている。

以下は Homebrew で pngquant と ImageMagick をインストールしてある場合のスクリプト例。

Automator - シェルスクリプトを実行 スクリプト

for f
do
    test -f "${f}" || continue
    /usr/local/bin/convert "${f}" -type GrayscaleMatte png:- \
    | /usr/local/bin/pngquant --speed 1 256 - \
    > "${f%.*}"-fs8g.png
done

テストでは 219 KB のファイルが 67 KB まで縮小した。