FileAPIとcanvasを使ってアカウント画像の登録機能を作る


FileAPIで画像の選択は簡単にできる

React使ってSPAを作るよ(21)の続きですが、今回はReactはあんまり関係ありません。
アカウント登録・更新のときにアイコン画像を設定できる機能を追加したいと思います。

こんな感じにしていきますよ~

fileapi

まずはHTMLとCSSで要素を作っていきます。

画像を登録しなかった場合のデフォルトの画像のパスを入れておくようにします。

もう、この時点で、labelをクリックしたらファイルを選択できるようになっています。
input type=”file”は非常に便利ですね。
ただこれだけだと、選んだファイルをそのまま送信するだけになってしまいますね。

普通にファイルを選んだだけだとプレビューもされないので、プレビューしつつ送信する画像のデータを用意するところまで、JavaScript(とjQuery)でやっちゃいましょう。

全体のコードはこうなっています。

何をやっているのか、上から順番に見ていきましょう。

FileAPIでblobを取得する

特別なことをしなくてもtype=”file”でファイルを選択することができました。
このときローカルにあるファイルのデータを見ていろいろすることができます。
まずはファイルが選択されたらchangeイベントで処理を始めます。

このとき、function()の引数を使って、ターゲットとなるファイルを特定しておきます。
今回の場合multiple(複数ファイル選択)ではないので、選択された画像があるかないか?の判定をして、あれば1つめのファイルを変数fileに格納しています。

わりとハマりやすいポイントらしいのですが、画像の読み込みが終わってないうちに画像のデータ(幅とか高さその他諸々)を取得しようとしても無理です。
そこでonloadイベントを使って、画像が読み込めてから処理をするというのが通例のようです。

さて画像が読み込めたら、reader.resultで画像のデータを見ることができます。
base64のコードはファイルによって微妙に異なるので、まず「base64,」という文字列を見つけて、その次の文字列を確認しています。
ここの文字列で画像形式が判別できます。

そして、BlobURLを取得します。
これは都度ファイルのURLを生成するもので、これを利用するとユーザーのファイルの置き場所などがわからないので、セキュリティ的にも良いようですね。

FileAPIとBlobURLについて詳しいことはこちらの記事を参照してください。

先ほど判定したMIMEタイプによって、JPEG、GIF、PNGであればメインの処理に入り、それ以外の謎のファイルであればエラーメッセージを表示して、選択したファイルを取り消します。
HTML側で「accept=”image/*”」と指定していても、たとえば.wmvファイルの拡張子を.pngに変えたりすることでファイルを選択することができてしまうので、MIMEタイプを必ずチェックしています。

用意しておいたcanvas要素に、画像を貼り付けるための準備をしておきます。

最後の行で、挿入するためのimageに先ほどのBlobURLを入れていますね。
これもファイルの読み込みをしたときと同じく、.onloadで画像の読み込みを待ちます。

そのあと、まずは画像の幅・高さを比較して、どちらが大きい画像なのかを調べます。
もし横長の画像なら高さを200pxとして、幅をその比率に合わせます。
縦長の画像ならその逆。

そしてcanvasのサイズをその画像のサイズに合わせ、drawImageで画像を貼り付けます。

.toDataURL()を使うことでcanvasの中身をbase64で取得することができます。
それをtype=”hidden”になっているinputのvalueに入れて、これを送信しようという魂胆ですね。

ユーザーが選んだ画像をそのままストレージに入れると重たいし、orientationがうまく取れなくて向きが変わってしまう問題などがあるので、これが一番楽ちんです。
いったんcanvasに描画しているのでorientationも関係なくなるし助かりますね。

せっかくだからドラッグ&ドロップも実装したい…

スポンサードリンク

菜摘

Web制作がメインですがときどきフライヤーデザインやCDラベルなどDTP系もやってます。 デザイナーだったはずがhtml/cssコーディングに目覚めた。 黒い画面は相変わらず怖い。 javascriptはこのごろちょっと頑張ってるよ。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です