SE_BOKUのまとめノート的ブログ

SE_BOKUが知ってること・勉強したこと・考えたことetc

ブラウザで手描きした画像をBase64テキストにエンコードする/プレーンJavaScript+Fabric.js

f:id:arakan_no_boku:20210508152042p:plain

目次

ブラウザで手書きした画像をBase64形式に変換するサンプル

レイアウトを定義するHTML部分と、Base64形式にそれを変換するJavaScript部分をわけて記載していきたいと思います。

HTML部分

ソースはこんな感じです。

<!DOCTYPE html>
<html lang="jp">
	<head>
		<!-- Required meta tags -->
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
		<link rel="stylesheet" href="https://fonts.xz.style/serve/inter.css" />
		<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@exampledev/new.css@1.1.2/new.min.css" />
		<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.3/fabric.js"></script>
		<title>動作確認</title>
	</head>
	<body>
		<h3>手書きした画像をBase64に変換する</h3>
		<table>
			<tr>
				<td>
					<div>
						<canvas id="fbcanvas" style="border: solid 1px red" width="600px" height="300px"></canvas>
					</div>
				</td>
			</tr>
			<tr>
				<td>
					<input type="button" id="tobase64btn" onclick="canvas_to_base64()" value="Base64変換" />
					<input type="button" id="clearbtn" onclick="canvas_clear()" value="クリアー" />
				</td>
			</tr>
			<tr>
				<td>
					<div>
						<textarea id="resultbase64" style="width: 100%; height: 300px" value=""></textarea>
					</div>
				</td>
			</tr>
		</table>
		<script type="text/javascript" src="js/canvas01.js"></script>
	</body>
</html>

CSSは、クラス指定が必要ないnew.cssを使ってます。

newcss.net

不要な場合は以下の2行を消せばいいです。

<link rel="stylesheet" href="https://fonts.xz.style/serve/inter.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@exampledev/new.css@1.1.2/new.min.css" />

HTML部分の補足

まず、Fabric.jsライブラリを読み込みます。

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.3/fabric.js">

手描きするエリアはCanvasで定義します。

  <canvas id="fbcanvas" style="border:solid 1px red" width="600px" height="300px"></canvas>

 JavaScript内でID指定で参照参照しています。

Canvasに描いた図を画像フォーマット(png)にしてBase64変換するJavaScriptの関数をキックするボタン。

<input type="button" id="tobase64btn" onclick="canvas_to_base64()" value="Base64変換" />

および、Canvas内をクリアするボタン

<input type="button" id="clearbtn" onclick="canvas_clear()" value="クリアー" />

 を追加します。 

そして、bodyの最後で本体のJavaScriptをロードしてます。

<script type="text/javascript" src="js/canvas01.js"></script>

JavaScript部分「canvas01.js」

手描き部分はブラシを使ったFREE DRAWINGを簡単にする「Fabric.js」を使います。 

fabricjs.com

現状、Free Drawingに関しては、ブラシの種類も少なくて、基本的な機能だけ提供されている成長中のライブラリです。

In the near future, we are planning to add more options for free drawing — various versions of a brush (e.g. spray-like or chalk-like). Also custom brush patterns, and an option to extend with your own, similar to Fabric image filters.

近い将来、さまざまなバージョンのブラシ(例えばスプレーまたはチョークのような)など、フリー描画のオプションを追加する予定です。

また、カスタムブラシパターンと、ファブリックイメージフィルタと同様に独自に拡張するオプションもあります。

Fabric.js以外はプレーンなJavaScriptです。

canvas01.js

var fbcanvas = new fabric.Canvas("fbcanvas", {
	isDrawingMode: true,
});
fabric.Object.prototype.transparentCorners = false;
fbcanvas.freeDrawingBrush = new fabric["PencilBrush"](fbcanvas);
fbcanvas.freeDrawingBrush.color = "black";
fbcanvas.freeDrawingBrush.width = 18;

function canvas_clear() {
	fbcanvas.clear();
	document.getElementById("resultbase64").value = "";
}

function canvas_to_base64() {
	let s = fbcanvas.toDataURL("image/png");
	document.getElementById("resultbase64").value = s;
}

fabric.Canvasオブジェクトを生成し、isDrawingMode: trueとすると、Free Drawingができるようになります。

あとは、ブラシオブジェクトを生成して、色と太さをセットしているだけです。

サンプルなので手抜きで色もブラシも固定にしてます。

Base64形式に変換する処理は「toDataURL」です。

今回は、Base64に変換した文字列を、textareaに表示するところまでをやります。

実行してみます

フォルダ構成は、HTMLのあるフォルダに「js」「css」のサブフォルダがあって、そこにJavaScriptcssを置いている想定です。

テストの際はローカルにWEBサーバーをたてて、http://localhost・・のようにURLを指定して動かすようにしないと、たぶん、ちゃんと動かないです。

f:id:arakan_no_boku:20210508234352p:plain

ここに適当に文字でも書いて、Base64変換ボタンを押します。

f:id:arakan_no_boku:20210508234528p:plain

すると、下に手描き画像イメージをBase64変換したテキストを表示します。

f:id:arakan_no_boku:20210508234639p:plain

OKですね。

Base64形式テキストについて補足

ちなみに。

このテキストは2つの部分にわかれます。

先頭部分の

data:image/png;base64,

と、後ろに続くデータ部です。

先頭部分がついた状態なら、imgタグにそのまま渡して画像を表示できます。

逆に、サーバー側の処理に画像データとして渡す場合は、この先頭部分を削除してデータ部分だけにしてやる必要があります。

こんなところですかね。

ではでは。