本日、JavaScriptで縮小画像の作成 | while(isプログラマ)のコメント欄にて、慎之助さんから下記のようにコメントがありました。
「画像を縮小して表示」サンプルと
「canvasで描いた絵をバイナリ形式でサーバーにPOST送信する方法 | while(isプログラマ)」のサンプルを元にして、
「JavaScriptで縮小画像を作成してサーバーにPOST送信する方法」を試行錯誤しながら作っていますが、なかなか出来ません。
そのやり方のサンプルを掲載されることを、とてもとても楽しみにいたしております。
canvasで描いた絵をバイナリ形式でサーバーにPOST送信する方法 | while(isプログラマ)を使って縮小画像をサーバーに送りたいのだけれども、できないということらしい。
自分も上記エントリーの最後に「できそうです」と書いているものの、実際に試したわけではないので、今回試してみました。
とりあえず、『JavaScriptで縮小画像の作成』で作ったサンプルページをもとに、それをPOST送信するようなプログラムを作ってみることにします。利用するサーバー側プログラムのPHPは『canvasで描いた絵をバイナリ形式でサーバーにPOST送信する方法』でも利用したPHPを何も変更せずに利用することに。
結論からいうと、できました。
サンプルページ:画像を縮小して表示してPOSTでサーバーに送信
画像をアップすると、その下にアップした画像を指定分縮小した画像が表示されます。ファイルを選択するとすぐにアップロードする仕組みになっているので、ネットに公開したくない画像を間違って選択してしまわないように注意してください。もし間違えた場合は、すぐに公開してもいい画像をアップロードしてください。
『JavaScriptで縮小画像の作成』で作ったサンプルページの変更点としては、jQueryを使ってなかったので、jQueryを呼び出し、base64形式の文字列をBLOB形式にするbase64ToBlobという関数とBLOB形式のファイルをPOSTで送信するsendImageBinary関数を追加しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
// バイナリ化した画像をPOSTで送る関数 // http://blog.sarabande.jp/post/30694191998 var sendImageBinary = function(blob) { var formData = new FormData(); formData.append('acceptImage', blob); $.ajax({ type: 'POST', url: 'image-accept2.php', data: formData, contentType: false, processData: false, success:function(date, dataType){ var $img = $('img'); var imgSrc = $img.attr('src'); $img.attr('src', ""); $img.attr('src', imgSrc + '?' + (new Date())*1); }, error: function(XMLHttpRequest, textStatus, errorThrown){ } }); }; // 引数のBase64の文字列をBlob形式にしている var base64ToBlob = function(base64){ var base64Data = base64.split(',')[1], // Data URLからBase64のデータ部分のみを取得 data = window.atob(base64Data), // base64形式の文字列をデコード buff = new ArrayBuffer(data.length), arr = new Uint8Array(buff), blob, i, dataLen; // blobの生成 for( i = 0, dataLen = data.length; i < dataLen; i++){ arr[i] = data.charCodeAt(i); } blob = new Blob([arr], {type: 'image/png'}); return blob; } |
後は、canvasのtoDataURLメソッドでBase64形式の文字列を取得し、それをbase64ToBlobの引数にいれて、さらにその戻り値をsendImageBinaryの引数にいれるということをしています。
1 2 3 |
// POST送信 var blob = base64ToBlob(canvas.toDataURL()); sendImageBinary(blob); |
ただ、そもそも慎之助さんがどこで躓いていたのかが分からないので、注意点を言っておくと、古いブラウザだと動きません。例えば、IEだと10以降でないと動きません。また、サーバーの設定でファイルの作成や書き込みができないようになっているとうまくいきませんし、アップする画像が大きい場合にもうまくいかない可能性があります。
さて、ここまできたら、ExifのOrientationを見たうえでcanvasに画像を表示できるJSライブラリ | while(isプログラマ)で書いた内容をもとに、Exifも考慮して縮小画像を作成し、POSTで送信するということもできるはずです。そこまでは実装してませんが、興味ある人は試してみてください。