昨今では画像アップロード処理をする際、サーバーサイドだけでなくフロントサイドでもリサイズ(圧縮)するのが主流になっています。
画像圧縮は、Javascriptのcanvas APIを使って実装するのが一般的ですが、canvasで画像圧縮処理を一から実装となると、それなりのコーディング量が必要となります。 そのため、よっぽどな理由がない限りはJavascriptライブラリを使用するのをオススメします。
今回は、代表的な画像圧縮ライブラリ「blueimp-load-image」を使用した実装例を紹介したいと思います。
blueimp-load-imageを使用した画像圧縮の実装例
blueimp-load-imageは画像加工処理を行うためのnpmライブラリです。 画像加工、リサイズ、回転情報の削除、プレビュー画像の作成などを簡単に実装することができます。
さっそく実装を見ていきましょう。
import * as loadImage from 'blueimp-load-image'; const resizeImageWorker = (imageFile, options = { maxHeight: 828, maxWidth: 1104, canvas: true, orientation: true, }) => { return new Promise((resolve) => { loadImage(imageFile, (canvas) => { const type = 'image/jpeg'; const dataUri = canvas.toDataURL(type); const bin = atob(dataUri.split(',')[1]); const buffer = new Uint8Array(bin.length); for (let i = 0; i < bin.length; i++) { buffer[i] = bin.charCodeAt(i); } resolve(new Blob([buffer.buffer], { type: type })) }, options); }); } function createProductImages(payload) { const { productRecipeId, productImage } = payload; return resizeImageWorker(productImage).then((blob) => { const params = new FormData(); params.append('product_image', blob); // リサイズ後の画像を画像アップロードAPIサーバーに連携 return axios.post(`/api/product_recipes/${productRecipeId}/product_images`, params, { headers: { 'content-type': 'multipart/form-data', }, }); }) }
商品レシピの画像をリサイズして画像アップロードAPIに連携するというサンプルプログラムになります。
resizeImageWorkerという関数で画像リサイズ処理を行っています。
blueimp-load-imageからimportしたloadImageという関数を使用します。 loadImageは非同期処理なのでPromise化して、resolveしてBlobを返却するという作りにしています。
resizeImageWorkerで返却されたBlobを画像アップロードAPIに送信することで処理が完了します。
たった10行ほどのコードでリサイズ処理が実装できてしまいます。
他に候補に上がったライブラリ
画像リサイズ処理を実装するにあたり他にもいくつかライブラリを試してみました。
今回は要件が合わなくて使用を見送りましたが、使い勝手が良いライブラリばかりなのでチェックしてみると良いでしょう。
imtool
IE11はサポート対象外であるためNGとしました。
実際に導入したところAPIが分かりやすく使いやすかったです。 IEがサポート対象外であればこちらを使用していたと思います。
jimp
commonJS方式のみサポートなのでNGとしました。
commonJSをサポートしている環境であれば有りだと思います。
pica
commonJS方式のみサポートなのでNGとしました。
commonJSをサポートしている環境であれば有りだと思います。