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

【ITニュース解説】圖片壓縮:用 Compressor.js 自動調整品質壓縮至指定大小

2025年10月04日に「Dev.to」が公開したITニュース「圖片壓縮:用 Compressor.js 自動調整品質壓縮至指定大小」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

ユーザーがアップロードする高画質画像のファイルサイズ問題を解決する。Compressor.jsを使い、目標サイズになるまで画質を自動で調整し、再帰的に画像を圧縮する仕組みを紹介する。WebP変換やサイズ制限もブラウザ側で完結し、サーバー負担を減らしつつ最適な画質とサイズを実現する。

ITニュース解説

ウェブサイト上でユーザーが画像をアップロードする機能は非常に一般的だが、最近のスマートフォンのカメラ性能向上により、撮影される画像のファイルサイズは数メガバイト(MB)にもなる。このような巨大な画像をそのままアップロードすると、画像の処理に時間がかかったり、サーバーのストレージを圧迫したり、ユーザーのデータ通信量を無駄に消費したりする問題が発生する。

これまでの画像圧縮ツールは、通常、圧縮の品質を固定値で設定するものが多い。例えば「品質を80%に設定」といった具合だ。しかし、この方法では、元画像のサイズや内容によっては、圧縮後のファイルサイズが依然として大きすぎたり、逆に圧縮しすぎて品質が大幅に劣化してしまったりする可能性がある。目標とするファイルサイズに確実に収めることは難しい。

そこで、今回紹介する技術は、JavaScriptライブラリである「Compressor.js」を活用し、画像を自動で効率的に圧縮する方法だ。この方法では、単に品質を固定するのではなく、以下の3つの重要な要件を満たすことを目指す。

第一に、圧縮後のファイルサイズが指定した目標値(例えば600KB)以下になるまで、画像の品質を自動的に調整して圧縮を試行する。これにより、必要以上に画像を劣化させることなく、目標サイズを確実に達成する。 第二に、画像をWebP形式に変換する。WebPはGoogleが開発した新しい画像フォーマットで、同じ画質であればJPEG形式に比べてファイルサイズを25〜35%削減できる。ウェブサイトの表示速度向上に大きく貢献する。 第三に、画像の縦横の最大サイズ(解像度)を制限する。スマートフォンで撮影された4Kや8Kの高解像度写真も、例えば幅2560ピクセル、高さ1440ピクセルといった実用的なサイズに縮小されるため、不要に大きな画像データが転送・保存されるのを防ぐ。

この画像圧縮機能の核心にあるのは「再帰圧縮」という考え方だ。これは、画像を一度圧縮して終わりではなく、目標サイズに達するまで何度も圧縮を繰り返す処理を指す。具体的な手順は次のようになる。

まず、画像を最高の品質(品質パラメータを1.0、つまり100%)で一度圧縮する。 次に、圧縮後の画像ファイルのサイズが目標サイズ(例えば600KB)を超えているかを確認する。 もし目標サイズを超えていたら、画像の品質を少しだけ下げる(例えば品質パラメータを0.05減らす)。そして、その新しい品質設定で画像を再度圧縮する。 この「圧縮→サイズチェック→品質調整→再圧縮」という一連のステップを、圧縮後のファイルサイズが目標サイズ以下になるか、あるいは品質パラメータがこれ以上下げられない下限値(例えば0.40、つまり40%)に達するまで、繰り返し実行する。

この再帰的なアプローチにより、開発者は圧縮後のファイルサイズをコントロールしつつ、可能な限り元の画像の品質を維持できる。過度な圧縮による品質劣化も、目標サイズ達成のための不必要な品質低下も防げるのだ。

この機能を実装するために「Compressor.js」ライブラリをウェブページに組み込む。これはCDN(コンテンツデリバリーネットワーク)経由で簡単に利用できる。<script src="https://cdn.jsdelivr.net/npm/compressorjs@1.2.1/dist/compressor.min.js"></script>のようにHTMLファイル内に記述するだけで、ブラウザがこのライブラリを読み込み、すぐに画像の圧縮処理を行えるようになる。このライブラリはブラウザ上で動作するため、画像をサーバーにアップロードする前にクライアント側で処理が完結し、サーバーへの負荷を減らすことができる。

実際のウェブページには、ユーザーが画像ファイルを選択するためのファイル入力欄(<input type="file" id="upload" accept="image/*" />)と、圧縮後の画像を表示するためのプレビュー領域(<img id="preview" />)をHTMLで用意する。

JavaScriptコードの最も重要な部分は、前述の再帰圧縮ロジックを実装する「compressWithFloor」という関数だ。この関数は、圧縮したい元の画像ファイル、目標とするファイルサイズ(バイト単位)、品質の下限値、そして品質を一度に下げる幅、という4つの情報を受け取る。

関数内部では、PromiseというJavaScriptの非同期処理の仕組みを使って、圧縮処理の完了を待てるように設計されている。まず品質パラメータqを1.0(最高品質)に初期設定し、attemptという内部関数を定義する。このattempt関数が再帰圧縮の具体的な処理を担当する。

attempt関数の中では、new Compressor(file, { ... })という形でCompressor.jsのインスタンスを生成し、圧縮を実行する。ここで重要な設定がいくつかある。

  • quality: q: 現在の品質パラメータqを指定する。
  • mimeType: "image/webp": 出力形式を強制的にWebPに指定する。元の画像がJPEGやPNGであってもWebPに変換される。
  • maxWidth: 2560, maxHeight: 1440: 画像の最大寸法を指定する。元の画像がこれより大きい場合は、縦横比を保ちながら指定サイズに縮小される。これより小さい場合は、そのままのサイズが維持される。

Compressor.jsでの圧縮が成功すると、successコールバック関数が呼び出され、圧縮された画像データがblobという形式で渡される。ここで、blob.size(圧縮後のファイルサイズ)とtargetSize(目標サイズ)を比較する。

もし圧縮後のファイルサイズが目標サイズより大きく、かつ品質を下げる余地がある(q - step >= floor)ならば、品質パラメータqstep分だけ減らし、再度attempt()関数を呼び出す。これがまさに再帰圧縮の処理だ。 一方、ファイルサイズが目標サイズ以下になった場合、または品質が下限値(floor)に達した場合は、それ以上の圧縮は不要と判断し、圧縮されたblobデータを返して処理を終了する。 もし圧縮中にエラーが発生した場合は、errorコールバック関数が呼び出され、エラーを通知する。

圧縮された画像データ(Blobオブジェクト)は、ブラウザで直接表示したり、API経由でサーバーに送信したりするために、Base64形式というテキストデータに変換する必要がある。この変換のために「blobToBase64」という補助関数が用意されている。この関数はFileReaderというブラウザの機能を使って、BlobデータをBase64データURL形式に変換する。

最後に、これらの要素を組み合わせて、ユーザーが画像をアップロードした際の全体の処理フローを構築する。 ユーザーがファイル入力欄で画像を選択すると、changeイベントが発火し、イベントリスナー内の処理が実行される。 まず、選択されたファイルが取得され、もしファイルサイズがすでに目標サイズ以下であれば、圧縮はせずにそのままプレビュー表示を行い、処理を終える。 そうでなければ、前述の「compressWithFloor」関数を呼び出して画像を圧縮する。この処理は非同期なので、awaitキーワードを使って完了を待つ。 圧縮が完了すると、返されたBlobデータを「blobToBase64」関数でBase64形式に変換し、そのデータを使ってプレビュー用の<img>タグのsrc属性を更新することで、圧縮された画像をブラウザに表示する。 同時に、元のファイル名から拡張子を取り除き、例えば「-compress.webp」といったサフィックスを付けて新しいファイル名を作成する。そして、一時的なダウンロードリンクを生成し、それを自動的にクリックすることで、圧縮された画像をユーザーのコンピューターにダウンロードさせる。 もし圧縮中に何らかの問題が発生した場合は、try...catchブロックによってエラーが捕捉され、コンソールにエラーメッセージが表示される。

具体的な圧縮プロセスの例として、5MBの画像がアップロードされた場合を考えてみよう。 最初の圧縮(品質1.00)で1200KBになった場合、目標の600KBを超えているので、品質を0.95に下げて再圧縮する。 次に950KBになったら、まだ大きいので品質を0.90に下げて再圧縮。 750KB、そして580KBになったところで、目標の600KB以下になったため、ここで圧縮処理は完了する。最終的な画像サイズは580KBとなる。 もし、元の画像の品質が非常に低く、品質を最低下限値(0.40)まで下げても目標サイズ以下にならない場合でも、品質の下限に達した時点で圧縮を停止するため、画像が判別不能なほど過度に劣化するのを防ぐことができる。

この画像圧縮機能は、ユーザーがウェブサイトに画像をアップロードする際の体験を大幅に向上させ、同時にウェブサイト運営側のサーバー負荷やストレージコストを削減する有効な手段となる。システムエンジニアにとって、このようなクライアントサイドでの効率的なデータ処理は、パフォーマンス最適化の重要なスキルの一つだ。

関連コンテンツ

関連IT用語