いろんな画像を一発で特定の形式に整えてくれるプログラムを作成した話
編集部員向けに、画像を自動でGIGAZINEに掲載する時の形式に整えるツールを作成しました。せっかくなので、作り方を記事にしてみました。
画像を変換する方法は多数存在していますが、今回はJavaScriptのライブラリである「sharp」を使用します。
sharp - npm
https://www.npmjs.com/package/sharp
最初に開発環境を整えるため、Node.jsをインストールします。Node.jsのダウンロードページで「Prebuilt Installer」をクリックし、「Download Node.js v○○.○○.○」をクリック。
ダウンロードしたmsiファイルをダブルクリックして実行します。
Node.jsのセットアップウィザードが起動するので「Next」をクリック。
ライセンスに同意して「Next」をクリックします。
インストール先のフォルダを確認して「Next」をクリック。
何をインストールするのかを設定できますが、今回は特に何も変更せず「Next」をクリックすればOK。
「Next」をクリック。
「Install」をクリックします。
インストールが完了したら「Finish」をクリックしてインストーラーを閉じます。
続いて必要なライブラリをセットアップしていきます。コマンドプロンプトを起動して「cd」コマンドで作業用のフォルダに移動し、下記のコマンドを入力。
npm init -y
npm install sharp@^0.29.3 fs-extra
エクスプローラーから作業用フォルダ内に「index.js」という名前のファイルを作成し、メモ帳などのテキストエディタで開いて下記のコードを入力します。
const fs = require("fs-extra");
const sharp = require("sharp");
const dirname = process.cwd();
const input = fs.readFileSync(dirname + "/00.png");
sharp(input).toFile(dirname + "/00.webp");
作業用フォルダに「00.png」という名前で実験用のファイルを保存してからコマンドプロンプトに戻り、「node index.js」とコマンドを実行すると下図のように「00.webp」が生成されました。sharpの標準設定では、クオリティ「80」での非可逆圧縮が行われます。元の「00.png」が81KBだったのに対し、23KBまでサイズを削減できています。
このままでは毎回決まった名前の画像ファイルしか変換できないため、引数で変換したいファイルを設定できるようにします。Node.jsではコマンド全体をスペースで切った配列が「process.argv」に代入されており、配列の最初の2要素が「node」と「index.js」なので以下のように「process.argv」の中身をfor文で順番に処理すればOK。
const fs = require("fs-extra");
const sharp = require("sharp");
const dirname = process.cwd();
for(let i=2; i<process.argv.length; i++){
const fileName = process.argv[i]; // 例:00.png
const input = fs.readFileSync(dirname + "/" + fileName);
const baseFileName = fileName.split(".")[0]; // 例:00
sharp(input).toFile(dirname + "/" + baseFileName + ".webp");
}
これで「node index.js 00.png」のようにファイルを指定すればWebP形式へと変換してくれます。また、WebPよりもさらに圧縮率が高まると言われるAVIF形式に変換したい場合は拡張子を「.avif」に変更します。
AVIF形式にした画像はこんな感じ。sharpの標準設定ではクオリティ「50」の非可逆圧縮が行われます。WebP形式の画像のサイズは23KBでしたが、AVIFでは11KBとさらに軽量化できました。下のAVIF形式の画像の表示に問題がある場合、この「いろんな画像を一発で特定の形式に整えてくれるプログラムを作成した話」記事の最下部にある「誤字脱字の指摘」フォームより端末の種類やブラウザの情報を伝えてもらえると速攻で連絡が届くので助かります!
変換元となったPNG形式の画像はこんな感じ。上のAVIF形式の画像と何が違うのか、目視では全く分かりません。
AVIFの方が圧縮率は高まるのですが、GIGAZINEでの採用を考えた場合には、AVIFは2024年に主要ブラウザでサポートされるBaseline化されたとは言え人口カバー率が93.35%しかなかったり、拡大表示のために別タブで画像を開こうとするとブラウザによっては代わりにダウンロードされてしまうなどの問題があります。
WebPはBaseline化してから時間がたっていることもあり、人口カバー率は96.4%とのこと。拡大表示も問題ありません。というわけで、ここからはWebPへの変換に絞って進めていきます。
プログラムの大まかな流れはできており、細部を詰めていけば問題なく使用できそうです。しかしプログラムのままではそもそもITエンジニアではない編集部員が使うには難があるため、次回は作成したプログラムを実行ファイル化して配布できるようにしていきます。
なお、今回の記事はAVIF形式の例として掲載した1枚の画像を除き、WebP形式の画像を使用して作成してみました。もし何か表示に問題があれば、この「https://gigazine.net/news/20241005-image-webp-avif/」ページ最下部の「誤字脱字の指摘」フォームを使用すると担当者に直通で連絡できるので報告していただけると助かります。
メンバーになってGIGAZINEをサポートする