1
3

More than 3 years have passed since last update.

【Javascript】CreateJSによる手書き入力インタフェース

Last updated at Posted at 2020-09-06

はじめに

手書き文字をAIに判別させるデータは、MNISTなどでデータがフリーで公開されています。そのデータを利用すると、簡単に識別モデルを作ったり、推論させたりすることができます。しかし、実際に自分が書いた文字をAIに食わせてみたいと思っても、デジタルデータにするのが意外と面倒くさいですよね。そこで、手書き文字をデジタルデータへ簡単に変換できるInterfaceをjavascript(CreateJS)で作成してみました。

プログラム

javascript(CreateJS)を使用したプログラムです。

tegaki_Interface.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <script src="https://code.createjs.com/1.0.0/createjs.min.js"> </script>
</head>
<body>
  描画キャンバス
  <div><canvas id="WriteCanvas" width="240" height="240"></canvas></div>
  <div><canvas id="ButtonCanvas" width="240" height="100"></canvas></div>
  PNG形式
  <div><img id="copyImg" width="240" height="240" background="#000000"></div>
</body>
</html>

<script>
window.addEventListener("load", init);
function init() {

    // --------------------------------------------------------------
    // Stage1オブジェクト:WriteCanvas
    // --------------------------------------------------------------
    var stage1 = new createjs.Stage("WriteCanvas");

    // タッチイベントが有効なブラウザの場合、
    // CreateJSでタッチイベントを扱えるようにする
    if (createjs.Touch.isSupported()) {
        createjs.Touch.enable(stage1);
    }

    var shape = new createjs.Shape();   // シェイプを作成
    stage1.addChild(shape);             // ステージに配置

    handleClick_reset();

    // ステージ上でマウスボタンを押した時のイベント設定
    stage1.addEventListener("stagemousedown", handleDown);

    // マウスを押した時に実行される
    function handleDown(event) {

        var paintColor = "#FFFFFF"                      // 筆ペンの色

        // 線の描画を開始
        shape.graphics
                .beginStroke(paintColor)                // 指定のカラーで描画
                .setStrokeStyle(20, "round")            // 線の太さ、形
                .moveTo(event.stageX, event.stageY);    // 描画開始位置を指定

        // ステージ上でマウスを動かした時と離した時のイベント設定
        stage1.addEventListener("stagemousemove", handleMove);
        stage1.addEventListener("stagemouseup", handleUp);
    }

    // マウスが動いた時に実行する
    function handleMove(event) {

        // マウス座標への線を引く
        shape.graphics.lineTo(event.stageX, event.stageY);
    }

    // マウスボタンが離された時に実行される
    function handleUp(event) {

        // マウス座標への線を引く
        shape.graphics.lineTo(event.stageX, event.stageY);

        // 線の描画を終了する
        shape.graphics.endStroke();

        // イベント解除
        stage1.removeEventListener("stagemousemove", handleMove);
        stage1.removeEventListener("stagemouseup", handleUp);
    }

    createjs.Ticker.timingMode = createjs.Ticker.RAF;
    createjs.Ticker.addEventListener("tick", onTick);

    function onTick() {
        stage1.update(); // Stageの描画を更新
    }

    // --------------------------------------------------------------
    // Stage2オブジェクト:ButtonCanvas
    // --------------------------------------------------------------
    var stage2 = new createjs.Stage("ButtonCanvas");
    stage2.enableMouseOver();

    // ボタンを作成
    var btn1 = createButton("PNG変換", 80, 30, "#0650c7");
    btn1.x = 20;
    btn1.y = 10;
    stage2.addChild(btn1);

    var btn2 = createButton("Reset!", 80, 30, "#d10a50");
    btn2.x = 110;
    btn2.y = 10;
    stage2.addChild(btn2);

    // イベントを登録
    btn1.addEventListener("click", handleClick_png);
    btn2.addEventListener("click", handleClick_reset);

    // PNG変換ボタン押下イベント
    function handleClick_png(event) {

        // Canvasタグから画像に変換
        stage1.update();
        var png = stage1.canvas.toDataURL();
        document.getElementById("copyImg").src = png;

        /*
        var w = window.open('about:blank');
        w.document.write("<img src='" + png + "'/>");
        */
    }

    // Rest!ボタン押下イベント
    function handleClick_reset(event) {

        // シェイプのグラフィックスを消去
        shape.graphics.clear();
        shape.graphics.beginFill("black");
        shape.graphics.drawRect(0, 0, 240, 240);
        shape.graphics.endFill();
        stage1.update();
        var png = stage1.canvas.toDataURL();
        document.getElementById("copyImg").src = png;
    }

    // 時間経過イベント
    createjs.Ticker.addEventListener("tick", handleTick);
    function handleTick() {

        // Stage2の描画を更新
        stage2.update();
    }

    /**
    * @param {String} text ボタンのラベル文言です。
    * @param {Number} width ボタンの横幅(単位はpx)です。
    * @param {Number} height ボタンの高さ(単位はpx)です。
    * @param {String} keyColor ボタンのキーカラーです。
    * @returns {createjs.Container} ボタンの参照を返します。
    */
    function createButton(text, width, height, keyColor) {

        // ボタン要素をグループ化
        var button = new createjs.Container();
        button.name = text; // ボタンに参考までに名称を入れておく(必須ではない)
        button.cursor = "pointer"; // ホバー時にカーソルを変更する

        // 通常時の座布団を作成
        var bgUp = new createjs.Shape();
        bgUp.graphics
              .setStrokeStyle(1.0)
              .beginStroke(keyColor)
              .beginFill("white")
              .drawRoundRect(0.5, 0.5, width - 1.0, height - 1.0, 4);
        button.addChild(bgUp);
        bgUp.visible = true; // 表示する

        // ロールオーバー時の座布団を作成
        var bgOver = new createjs.Shape();
        bgOver.graphics
              .beginFill(keyColor)
              .drawRoundRect(0, 0, width, height, 4);
        bgOver.visible = false; // 非表示にする
        button.addChild(bgOver);

        // ラベルを作成
        var label = new createjs.Text(text, "18px sans-serif", keyColor);
        label.x = width / 2;
        label.y = height / 2;
        label.textAlign = "center";
        label.textBaseline = "middle";
        button.addChild(label);

        // ロールオーバーイベントを登録
        button.addEventListener("mouseover", handleMouseOver);
        button.addEventListener("mouseout", handleMouseOut);

        // マウスオーバイベント
        function handleMouseOver(event) {
            bgUp.visble = false;
            bgOver.visible = true;
            label.color = "white";
        }

        // マウスアウトイベント
        function handleMouseOut(event) {
            bgUp.visble = true;
            bgOver.visible = false;
            label.color = keyColor;
        }

        return button;
    }
}
</script>

プログラム実行

Tegaki_Interface.html」をローカルPCなどに保存して、実行(ブラウザで表示)してみてください。
手書き文字デジタルデータ(PNG形式)に変換することができました😊🎉

参考

ics.mediaさんの「CreateJS でお絵描きツールを作ろう」記事を参考にさせて頂きました😌

以上

この記事に記載した技術を応用して作成した「【MNIST】自分の数字をAIに認識させよう」の記事もありますので、こちらもよければ併せてどうぞ。

お疲れ様でした😉!

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3