JavaScript | html2canvasで生成した画像にPHPに送信する

2023-10-25JavaScript DOM操作,JavaScript

JavaScript | html2canvasで生成した画像にPHPに送信する

JavaScriptのhtml2canvasで生成した画像を直接PHPに送信する方法とサンプルコードを紹介しています。

html2canvasで生成した画像をPHPに送信するサンプルコード

html2canvasのcanvas.toDataURL()メソッドで生成した画像データは、そのままPHPに送信しても正常に受け取れません。
しかし、一旦ダウンロードしてアップロードという作業は手間ですので、直接PHPに送信したいところです。

PHPに送信する場合、base64の画像データではなく、blobの画像データで送信する必要があります。
html2canvasにはcanvas.toblob()というメソッドも用意されていますが、これを利用する場合は一度<canvas>要素に描画する必要がありそうで躓きました。

最終的にcanvas.toDataURL()メソッドで生成したbase64の画像データをblobの画像データに変換する関数を用意して解決しました。

// base64をblobに変換する関数
function dataURItoBlob(dataURI) {
	var byteString = atob(dataURI.split(',')[1]);
	var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
	var ab = new ArrayBuffer(byteString.length);
	var ia = new Uint8Array(ab);
	for (var i = 0; i < byteString.length; i++) {
		ia[i] = byteString.charCodeAt(i);
	}
	return new Blob([ab], { type: mimeString });
}

// html2canvas
html2canvas(document.querySelector('#container'), {
	// 処理オプション
	// windowWidth: 800,
	// width: 800,
	// scale: 2
}).then(canvas => {

	// base64画像データを生成
	let base64 = canvas.toDataURL('image/png');
	// base64をblobに変換
	let blob = dataURItoBlob(base64);
	// 送信データを作成
	const formData = new FormData();
	// 送信データにblob画像データを追加(データ名,画像データ,ファイル名)
	formData.append('image', blob, 'test.png');

	// PHPにPOST送信
	let xhr = new XMLHttpRequest();
	xhr.open('POST', 'upload.php', true);
	xhr.onreadystatechange = function (r) {
		if (xhr.readyState === 4 && xhr.status === 200) {
			// レスポンス処理
			console.log(xhr.response);
		}
	};
	xhr.send(formData);

});

画像の送信先ファイル(upload.php)は最小構成で以下のPHPコードとなっています。

// 送信データに画像があるか確認
if (isset($_FILES['image'])) {

	// 画像を保存するディレクトリがなければ作成
	if (!file_exists('images')) {
		mkdir('images', 0777);
	}

	// アップロード画像を保存 move_uploaded_file(送信ファイル, 保存先のファイル名)
	if (move_uploaded_file($_FILES['image']['tmp_name'], 'images/' . $_FILES['image']['name'])) {
		echo '画像が正常にアップロードされました。';
	} else {
		echo '画像のアップロードに失敗しました。';
	}
} else {
	echo '送信データが不足しています。';
}

上記コードはXMLHttpRequest()メソッドで記述していますが、fetch()メソッドでも機能します。

fetch('upload.php', {
	method: 'POST',
	body: formData
})
	.then(response => {
		if (response.ok) {
			return response.text();
		}
		throw new Error();
	})
	.then(data => {
		// レスポンス処理
		console.log(data);
	})
	.catch(error => {
		console.error(error);
	});