前回はQRコードの中央にちょっとした画像を貼り付ける「デザインQR」を作成しましたが、今回はその画像をアニメーションさせてみたいと思います。
アニメーションするQRコード作ってみた。
— 勝部麻季人 🍮 (@katsube) 2019年6月8日
これくらいの大きさならQRコードリーダーも認識してくれる。紙はムリだけどデジタルサイネージとかWebで出すのに良いかもね。
(キャラはUNITYちゃん) pic.twitter.com/4TzPShoTmk
アニメQRを作成する
準備
適当なディレクトリ作成し、package.jsonを作成後に、node-qrcodeとnode-canvasモジュール、GIFアニメを簡単に作成できるgifencoderをインストールします。
$ mkdir qr-anime && cd qr-anime $ npm init $ npm install qrcode canvas gifencoder
アニメーションするための素材ですが、今回はユニティちゃんを利用させていただきました。 unity-chan.com
アニメーションのフレーム毎にキャラを切り出して保存してあります。
ベースとなるQRコードを作成
作業を2段階に分けました。まずは基本的なQRコードを生成します。
コードは以下の通り。
const QRCode = require('qrcode'); // QRコードの設定準備 const file = "qr.png"; const segment = [ { data:"UNITY-CHAN!\n", mode:"byte"}, { data:"http://unity-chan.com/", mode:"byte"} ]; const options = { width: 164, color:{ dark: '#FF3300FF', // QRコードの色 light: '#FFFFFFFF' // 背景色 } }; // QRコード生成 QRCode.toFile(file, segment, options);
詳細は過去記事を参照ください。 blog.katsubemakito.net
アニメーションさせる
次に先ほど作成したQRコードにアニメを付けていきます。GIFアニメなので要はパラパラ漫画ですね。1フレームずつ画像を作成しgifencoderに渡すと最終的にGIFアニメとして出力してくれます。
const { createCanvas, loadImage } = require('canvas'); const GIFEncoder = require('gifencoder'); const fs = require('fs'); const WIDTH = 164; // 画像サイズ X const HEIGHT = 164; // 画像サイズ Y const GIFFILE = 'UnityQR.gif'; // 出力ファイル名 const makeAnimeQR = async () => { // アセット読み込み const asset = { qr: await loadImage('./qr.png'), //QRは事前に作成 chara:[ await loadImage('./image/s1.png'), await loadImage('./image/s2.png'), await loadImage('./image/s3.png'), await loadImage('./image/s4.png'), await loadImage('./image/s5.png'), await loadImage('./image/s6.png'), await loadImage('./image/s7.png'), await loadImage('./image/s8.png') ] }; // アニメGIF設定 const encoder = new GIFEncoder(WIDTH, HEIGHT); encoder.createReadStream().pipe( fs.createWriteStream(GIFFILE) ); encoder.start(); encoder.setRepeat(0); // 0:リピートあり, -1:なし encoder.setDelay(110); // フレーム間隔(ミリ秒) encoder.setQuality(10); // 画像品質 // canvas準備 const canvas = createCanvas(WIDTH, HEIGHT); const ctx = canvas.getContext('2d'); // フレーム生成 for( let i=0; i<asset.chara.length; i++ ){ const qr = asset.qr; const icon = asset.chara[i]; const left = Math.floor((canvas.width - icon.width) / 2); // x const top = Math.floor((canvas.height - icon.height) / 2); // y // 画像を載せる ctx.clearRect(0 ,0, canvas.width, canvas.height); //リセット ctx.drawImage(qr, 0, 0); //QR ctx.drawImage(icon, left, top); //UNITY CHAN // 作成者名も入れておく ctx.fillStyle = '#FF3300'; ctx.fillText('@katsube', canvas.width-50, canvas.height-2); // フレームに追加 encoder.addFrame(ctx); } encoder.finish(); }; makeAnimeQR();
雑なコードですみませんw
最初に貼り付けたツイートにも書きましたが、デジタルサイネージやWebページなどで表示すると目立って良いかもしれませんね。今回利用したアニメはちょっと運動量が多いので場合によってはうざく感じるかもしれませんので、キャラがまばたきをする、髪が揺れるといった細かい演出をするだけでも印象が違ってくると思います。
あと今回はNodeで作成しましたが、通常は画像編集ソフトなどで作れば良いですw (なぜ書いた←)