🦥

JSでフォームに登録した画像を圧縮して保存する

2023/11/08に公開

はじめに

JavaScriptを使用して画像リサイズ処理を実装した際の備忘録です。
リサイズする方法はいくつかありますが、この記事ではbrowser-image-compressionを使用して実装した方法を記載します。
画像のファイルサイズを縮小することで、ウェブサイトの読み込み速度を向上させることができます。

前提条件

  • browser-image-compressionを使用する

browser-image-compressionとは

browser-image-compressionは、ブラウザ上で画像を圧縮するためのJavaScriptモジュールです。
https://www.npmjs.com/package/browser-image-compression?activeTab=readme

実装方法

例として、最大サイズ5MBで、幅または高さが1600ピクセル以下に画像を圧縮し、サーバーにアップロードすることを想定して実装していきます。

インストール方法

npm や yarnでインストールする。

npm install browser-image-compression --save
# or
yarn add browser-image-compression

CDNなどで読み込んで利用できるようにしてください。

<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/browser-image-compression@2.0.0/dist/browser-image-compression.js"></script>

importして利用する

import imageCompression from "browser-image-compression";

これで、以下のようなメソッドを使って画像を圧縮することが可能になりました。

imageCompression(file, options);

実装例

JavaScriptの実装例です。
先述した通り、最大サイズ5MB以下で、幅または高さが1600ピクセル以下になるように画像を圧縮します。
また、複数の画像ファイルがリクエストされることを想定し、全ての画像が圧縮されるよう実装しています。

async function uploadImages(files) {
  const formData = new FormData();
  const options = {
    maxSizeMB: 5,
    maxWidthOrHeight: 1600
  };

  for (const file of files) {
    const compressedFile = await imageCompression(file, options);
    formData.append("images", compressedFile);
  }

  try {
    const response = await fetch("/image/upload", {
      method: "POST",
      body: formData
    });

    if (!response.ok) {
      throw new Error(`Failed to upload images: ${response.statusText}`);
    }

    console.log("Upload successful");
  } catch (error) {
    console.error(error);
  }
}

軽く実装の解説をします。

options

const options = {
  maxSizeMB: 5,
  maxWidthOrHeight: 1600
};

このようにオプションを指定して、サイズやピクセル数を定義しています。
他にもいくつかオプションが用意されています。詳しくはbrowser-image-compression Readmeを参照してください。

async/await

実装の通りasync/awaitを利用して、画像の圧縮が完了するまでと、画像のPOSTが完了するまで待機しています。
JavaScriptで画像の圧縮を実現するためには、圧縮が完了するまでの待機は必須の実装かと思います。

まとめ

browser-image-compressionを使用することで、画像の圧縮を簡単に実装できました。
画像の圧縮は、ウェブサイトの読み込み速度の改善などのUX向上にも繋がります。
覚えておいて損はなさそうだと思いました。

Discussion