17
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

nemAdvent Calendar 2021

Day 14

Symbolのアドレスを読み取る簡易QRコードスキャナを作成する

Last updated at Posted at 2021-12-20

ブロックチェーン上のトークンはアドレスと呼ばれる文字列でやり取りされます。
ただ、このアドレスは非常に長いために目で見て覚えるのは困難です。
視認性の高いネームスペースが普及するにはまだ少し時間がかかるかもしれません。

今回はイベントなどで相手方のアドレスを簡単に読み取れる簡易QRコードスキャナをブラウザ上で実装してみましょう。

まず検証環境を構築します。

今回Webカメラを使用するので、ブラウザのセキュリティ対策のためhttps対応のノードに接続してください。

QRコードライブラリのインポート
(script = document.createElement('script')).src = 'https://xembook.github.io/sigann/jsQR.js';
document.getElementsByTagName('head')[0].appendChild(script);

githubのxembook/sigannレポジトリにjsQRを置いていますのでインポートしてください。

スキャナスクリプトの実行
var isMovieScanning = false;
var video = document.createElement("video");
var canvasElement= document.createElement('canvas');
var canvas = canvasElement.getContext("2d");

document.getElementsByTagName('body')[0].appendChild(canvasElement);

function drawLine(begin, end, color) {
    canvas.beginPath();
    canvas.moveTo(begin.x, begin.y);
    canvas.lineTo(end.x, end.y);
    canvas.lineWidth = 4;
    canvas.strokeStyle = color;
    canvas.stroke();
}

function tick() {
    if(!isMovieScanning){return;}
    if (video.readyState === video.HAVE_ENOUGH_DATA) {
        canvasElement.hidden = false;
        canvasElement.width  = video.videoWidth;
        canvasElement.height = video.videoHeight;
        getCode(video);
    }
    requestAnimationFrame(tick);
}

function getCode(src){

    canvas.drawImage(src, 0, 0, canvasElement.width, canvasElement.height);
    var imageData = canvas.getImageData(0, 0, canvasElement.width, canvasElement.height);
    var code = jsQR(imageData.data, imageData.width, imageData.height, {inversionAttempts: "dontInvert"});

    if (code) {
        stopVideo();
        drawLine(code.location.topLeftCorner        , code.location.topRightCorner      ,"#FF3B58");
        drawLine(code.location.topRightCorner       , code.location.bottomRightCorner   ,"#FF3B58");
        drawLine(code.location.bottomRightCorner    , code.location.bottomLeftCorner    ,"#FF3B58");
        drawLine(code.location.bottomLeftCorner     , code.location.topLeftCorner       ,"#FF3B58");
        parseData(code);
    }
}

function startVideo(){

    isMovieScanning = true;
    navigator.mediaDevices.getUserMedia({
        video: {
            facingMode: "environment"
        }
    })
    .then(function(stream) {
        video.srcObject = stream;
        window.localStream = stream;
        video.setAttribute("playsinline", true);
        video.play();
        requestAnimationFrame(tick);
    });
}

function stopVideo(){
    isMovieScanning = false;
    if(window.localStream != undefined){
        window.localStream.getTracks().forEach( (track) => {
            track.stop();
        });
    }
}

function clearRect(){
    canvas.clearRect(0, 0, canvasElement.width, canvasElement.height);
}

function parseData(code){
    json = JSON.parse(code.data);
    address = sym.Address.createFromRawAddress(json.data.address.address);
    console.log(address)
}

startVideo();

最後の行のstartVideo();を実行するとQRスキャナがブラウザ上で立ち上がります。
お手元のSymbolアドレスのQRコードをかざしてみてください。

image.png

はい、取れました。
止めるときはstopVideo();で止まります。

さいごに

これをウェブサービスとしてビジネスするにはセキュリティ的にいろいろと問題点はあります。
しかし、サーバに載せずにローカルのHTMLファイルで完結してしまうので、ちょっとしたイベントにPCを持ち出して使用する程度であれば、QRコードスキャナはもう誰にでも作れるところまで来ていることを感じていただければ幸いです。

17
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
17
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?