JavaScriptで縮小画像を作成してサーバーにPOST送信する方法

本日、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関数を追加しています。

// バイナリ化した画像を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の引数にいれるということをしています。

// POST送信
var blob = base64ToBlob(canvas.toDataURL());
sendImageBinary(blob);

ただ、そもそも慎之助さんがどこで躓いていたのかが分からないので、注意点を言っておくと、古いブラウザだと動きません。例えば、IEだと10以降でないと動きません。また、サーバーの設定でファイルの作成や書き込みができないようになっているとうまくいきませんし、アップする画像が大きい場合にもうまくいかない可能性があります。

さて、ここまできたら、ExifのOrientationを見たうえでcanvasに画像を表示できるJSライブラリ | while(isプログラマ)で書いた内容をもとに、Exifも考慮して縮小画像を作成し、POSTで送信するということもできるはずです。そこまでは実装してませんが、興味ある人は試してみてください。

コメント

  1. 慎之助 より:

    (送る事が出来ましたので、全文を再送致します。)

    amyuさま、ありがとうございます。
    「JavaScriptで縮小画像を作成してサーバーにPOST送信する方法」で躓いてコメントさせて頂きました慎之助です。
    このように早く完成されたのには驚きと共に感動いたしました。しかもシンプルなプログラムで。

    このプログラムは私にとって、とても高度な内容です。
    もっと私には勉強する事が必要だと感じました。
    私の説明不足でしたが、躓いていた内容は初心者レベルで、下記の内容です。

    既存の
    〈form action=”abc.cgi” method=”post” enctype=”multipart/form-data”〉
    〈input type=”file” name=”upup”〉
    〈input type=”submit” name=”submit” value=”送信”〉
    〈input type=”reset” value=”リセット”〉〈/form〉
    を、

    送信ボタンを押すとJavaScriptでリサイズされた画像(upup)をサーバへ送る方法です。できましたらPHPを使わずに、JavaScriptだけ、もしくはperlを使ってです。

    たぶん私以外でも、これで躓いている人が世界中にたくさんいると思います。(作成に2週間 試行錯誤しながら日本語や英語でもググってみましたが解決できるブログやサイトはありませんでした。)

    スマホサイトでリサイズして画像アップをするには、アプリなどを経由しないといけない不便さがあるので、これが解決されれば、たくさんの人が救われると思います。

    amyuさま、期待しています。ぜひとも救ってください。
    感謝しております。

  2. amyu より:

    うーん。残念ながら、Perlは分からないんですよね。
    JavaScriptだけって、サーバー側もJavaScriptでってことでしょうか? POST送信自体はクライアント側のJavaScriptでできますが、サーバーに保存するにはサーバー側のプログラムも必要ですよ。
    サーバー側のプログラムはただたんに受け取ったファイルを保存するだけなので、サンプルコードなら探せば見つかると思います。

    多分、下記ページに書いてあることとかそうじゃないかなと思います。
    『ファイルをアップロードさせる 』http://www.ksknet.net/perl/post_26.html

    お役にたてずにすみません。

  3. 通りすがり より:

    私も慎之助さんのようなことを行いたく、このサイトにたどり着きました。
    その結果リサイズした画像をFORMに含めてPOSTすることができました。
    素晴らしいコードを書いて頂きありがとうございます。

    参考までに私の書いたコードも載せておきます。
    ・[HTML 5] form.html – Pastebin.com
    https://pastebin.com/b5j9spXa
    ・[JavaScript] upload.js – Pastebin.com
    https://pastebin.com/rz5DKzUN
    ・[JavaScript] resize.js – Pastebin.com
    https://pastebin.com/5AGL756n
    ・[PHP] upload.php – Pastebin.com
    https://pastebin.com/t3wV53KY

タイトルとURLをコピーしました