Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】A bash loop that logs bytes and seconds for each PNG optimization step

2026年10月30日に「Dev.to」が公開したITニュース「A bash loop that logs bytes and seconds for each PNG optimization step」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

PNG画像を軽量化する際、複数のツールを組み合わせた各工程で、どれだけファイルサイズが減り、どれくらいの処理時間がかかったかを計測するbashスクリプトを紹介。このスクリプトを使えば、各ツールの効果や処理時間の比較、適用順序による違いなどを数値で確認でき、最適化戦略の検討に役立つ。

ITニュース解説

このニュース記事は、PNG画像ファイルのサイズを最適化する(つまり、ファイルサイズを小さくする)プロセスにおいて、どのツールをどの順序で使えば最も効果的か、そしてそれぞれの処理にどれくらいの時間がかかるかを検証するための具体的な方法を紹介している。システムエンジニア(SE)を目指す初心者にとって、このような「具体的な課題解決のためのスクリプト作成と検証」は非常に実践的な学びになる。

PNG画像は、Webサイトの表示速度やアプリケーションの容量に影響するため、いかに効率よく圧縮するかが重要である。しかし、圧縮ツールは様々な種類があり、それぞれ得意な処理や設定が異なる。複数のツールを組み合わせることで、より良い結果が得られることが多いが、その効果やコスト(処理時間)を客観的に測る方法は意外と知られていない。この記事で紹介されるシェルスクリプトは、その測定を自動化し、数値データとして可視化するための強力な手段を提供するものだ。

スクリプトの基本的な考え方は、まず対象となるPNG画像群を用意し、それらに対して二段階の圧縮処理を適用する。一つ目のツールは「pngquant」で、これは非可逆圧縮、つまり画質をわずかに犠牲にする代わりにファイルサイズを大幅に削減するパレット化という技術を使う。二つ目のツールは「oxipng」で、これは可逆圧縮、つまり画質を一切損なうことなく、ファイル内部の構造を最適化してサイズを削減する。これらの処理の前後でファイルサイズを測定し、さらに各処理にかかる時間を記録することで、それぞれのツールの貢献度とパフォーマンスを把握できるようにしている。

具体的には、スクリプトはBashというシェルスクリプト言語で書かれており、いくつかのコマンドを組み合わせて動作する。まず、now()という関数を定義しているが、これはperlという別の言語の機能を利用して、処理の開始時刻と終了時刻を高精度に取得するためのものだ。この高精度な時刻情報は、処理速度の比較に不可欠である。次に、mktemp -dコマンドで一時的にファイルを置くための新しいディレクトリを作成する。これは、元のファイルを直接変更することなく安全に処理を進めるための工夫だ。

そして、指定されたフォルダ内のすべてのPNGファイルに対して、forループを使って一つずつ処理を実行していく。basenameとcutコマンドは、ファイル名から「icon」や「photo」といったカテゴリを抽出し、後で結果を分類するのに役立てる。ファイルの処理が始まる直前でnow()関数を呼び出して最初のタイムスタンプ(t0)を記録する。

次に、pngquantコマンドを使って画像を最適化する。このコマンドには、画質の範囲を--quality=65-80で指定し、強制的に出力する--force、そして出力ファイルを一時ディレクトリ内のq.pngという名前で保存する--outputといったオプションが渡されている。pngquantの処理が終わった直後に再びnow()を呼び出して二番目のタイムスタンプ(t1)を記録する。

続いて、cpコマンドでpngquantで生成された一時ファイルq.pngをo.pngという名前でコピーする。これは、oxipngが直接q.pngを上書きしてしまうと、pngquant単体での結果を確認できなくなるため、元の状態を保ちつつ次の処理に進むための準備である。そのコピーに対してoxipng -o 4 --strip safe -q "$tmp/o.png"を実行する。-o 4は最適化レベルの指定で、-strip safeは色プロファイルなど重要な情報を保持しつつ不要な情報を削除するオプションだ。oxipngの処理が終わったら、もう一度now()を呼び出して最後のタイムスタンプを取得する。

これらの処理が終わった後、echoコマンドを使って、元のファイルのバイト数、pngquant後のバイト数、oxipng後のバイト数、そして記録した三つのタイムスタンプを一行のテキストとして出力する。wc -c <ファイル名というコマンドは、ファイルのバイト数を数えるためのものだ。

このforループによってファイルごとの詳細なデータが大量に出力されるが、それらをまとめて集計・整形するためにawkという強力なテキスト処理ツールが使われている。awkは、ファイル名のカテゴリ(例えば「icon」)ごとに、元のファイルサイズ、pngquant後のサイズ、oxipng後のサイズ、そしてpngquantとoxipngそれぞれの処理にかかった時間を合計していく。最終的に、ENDブロックで各カテゴリの合計値を見やすい形式で出力し、sortコマンドでカテゴリ名を基準に並べ替えている。このawkとsortの連携によって、個別のファイルデータから、より高レベルな分析に使える集計データが生成されるのだ。

実際にWikimedia CommonsのPNG画像を対象にこのスクリプトを実行した結果も示されている。例えば、アイコン、イラスト、写真、スクリーンショットといったカテゴリに分類された画像群に対して処理を行うと、pngquantだけで元のサイズの約68.3%削減、さらにoxipngを適用すると合計で約71.2%削減されたという。つまり、二段階目のoxipng処理によって、さらに約2.9%のファイルサイズ削減が実現できたわけだ。特に写真カテゴリでは、oxipngによる追加削減効果が大きかったことが示されている。

処理時間についても結果が出ており、全体の処理ではpngquantが約1.25秒、oxipngが約4.95秒かかったという。ここから、ファイルサイズの削減効果は大きいものの、oxipngの方がpngquantよりも時間を要することがわかる。また、より高い圧縮率を持つzopflipngというツールも検討されたが、処理時間が非常に長くなるため、今回のループには組み込まれなかった。これは、機能とパフォーマンスのバランスを考慮した選択である。

記事では、処理の順序が結果に影響することも指摘している。もしoxipngを先に、pngquantを後に実行すると、最終的なファイルサイズがわずかに大きくなる可能性がある。これはpngquantが新しいパレット化されたファイルを生成する際に、それ以前の可逆圧縮の効果が失われるためだと考察されている。このことから、非可逆圧縮であるpngquantを先に、その後に可逆圧縮であるoxipngを適用する順序が、これらのツールを組み合わせる上では効果的だと結論付けられる。

さらに、他の画像最適化サービス(ImgIng)で生成されたPNGファイルに対しても、このoxipngによる二段階目の最適化が有効である可能性が示唆されている。これは、特定のツールで最適化された画像でも、さらに別のツールで追加の最適化余地があることを意味し、既存のワークフローに組み込む価値があることを示している。

このスクリプトが示す結果は、少数のファイル、特定の環境での一度の実行に基づくものであるため、普遍的な真実として捉えるべきではない。画像の品質比較は行われておらず、ファイルサイズが小さくなったことだけを基準にしている点も注意が必要だ。しかし、このようなスクリプトを使って自身のプロジェクトの画像ファイルに対して検証を行うことで、最適な圧縮戦略を見つけるための客観的なデータを得られる。

このスクリプトは、CI/CD(継続的インテグレーション/継続的デリバリー)のパイプラインに組み込むことも考えられる。例えば、画像ファイルのサイズが大きくならないか、新しいツールのバージョンで圧縮率が変わらないかなどを自動的にチェックする仕組みとして活用できる。もし同じ入力ファイルに対して異なるバイト数が記録されるような非決定的な挙動が見られた場合、それはツールの信頼性に関わる問題であるため、デプロイ前にしっかりと調査する必要がある。

まとめると、このニュース記事は単にPNG圧縮ツールの性能比較を行うだけでなく、その比較を自動化し、データとして可視化するための実践的なシェルスクリプトとその検証プロセスを紹介している。システムエンジニアを目指す者にとって、このような具体的な課題設定、スクリプトによる解決策の実装、そして結果の分析という一連のプロセスは、問題解決能力と技術的知見を深める上で非常に価値のある学びとなるだろう。

関連コンテンツ

関連IT用語

関連ITニュース