ども、@kimihom です。
前回の記事で画像のリサイズはサーバーサイドでって話だったんだけど、調べてみると Canvas でリサイズまでできてしまうという衝撃の事実が判明し、それで簡単にリサイズを実装できてしまった。
またもや HTML5 の技術に驚かされることになったので、ここに記す。
JavaScript でリサイズするのが理想的である理由
まず何故 JavaScript 側でリサイズするのがいいのかというと、アップロード時のネットワーク負荷が劇的に下げられるからだ。サーバーサイドでリサイズするとなると、まずそのでかい画像をアップロードしなければならない。この時点で重い画像だとアップロードに数秒かかってしまう。
これを JavaScript、つまりフロントエンドでリサイズできれば、ネットワーク負荷を抑えてアップロードが可能だ。これも HTML5 から登場した Canvas のおかげではあるが、そのメリットを存分に享受しよう。
縦横比を合わせた画像のリサイズ
リサイズするならそのままの縦横比で小さくしたいところ。てことで以下のような感じで canvas タグを作って当てはめる感じでソースを書いていく。
var resizeImage = function(base64image, callback) { const MIN_SIZE = 1000; var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); var image = new Image(); image.crossOrigin = "Anonymous"; image.onload = function(event){ var dstWidth, dstHeight; if (this.width > this.height) { dstWidth = MIN_SIZE; dstHeight = this.height * MIN_SIZE / this.width; } else { dstHeight = MIN_SIZE; dstWidth = this.width * MIN_SIZE / this.height; } canvas.width = dstWidth; canvas.height = dstHeight; ctx.drawImage(this, 0, 0, this.width, this.height, 0, 0, dstWidth, dstHeight); callback(canvas.toDataURL()); }; image.src = base64image; };
前回の記事で画像をクロップする方法を書いたが、できればそのクロップをする前にこの処理を書くことが望ましい。やはり画像がでかいとその分 クロップの処理にも時間がかかり、カクカクになってしまうことがあるためである。
てことで3記事連載で書いてきた画像の流れとしては、以下の通りとなる。
- 画像をドラッグアンドドロップで File オブジェクト取得
- File オブジェクトの content-type や ファイルサイズの検証
- File オブジェクトを
readAsDataURL
で Base64 エンコード - Canvas を用いて画像のリサイズ
- cropper.js で画像の切り取り
- 画像を Blob 化
- S3 に画像をアップロード
割とこの手順を踏む必要のあるウェブアプリケーションは多いように思う。
この中では AWS-SDK, Canvas, File API などたくさんの技術を扱うが、それぞれしっかりと理解してコードを書いていこう。
関連記事
終わりに
最近の3連載で、HTML5による画像のアップロードを扱った。なかなか体系的にまとまっているドキュメントがなかったりするので、ファイル選択だけで満足してたようなウェブアプリケーションを所有している読者がいれば、この機会にドラッグアンドドロップやリサイズ、クロップなど学んでみてはいかがだろうか。