まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:canvas

サーバーサイドで動的に画像を作りたい、という要求を実現する方法はいくつかありますが、今回は Node.js から使えるライブラリ "node-canvas" を紹介します:
https://github.com/Automattic/node-canvas/


まず、このライブラリを使う上ではいくつかのネイティブライブラリが必要です。詳しくは上記オフィシャルページを参照いただきたいのですが、例えば Ubuntu 環境であれば以下のコマンドを最初に実行して、必要なネイティブライブラリをあらかじめ用意しておきます:
$ sudo apt-get install libcairo2-dev libjpeg8-dev libpango1.0-dev libgif-dev build-essential g++

ネイティブライブラリの導入後に、以下のコマンドで node-canvas をインストールします:
$ npm install canvas

ちなみに、Bluemix の SDK for Node.js ランタイムを使う場合には上記のネイティブライブラリが導入されたビルドパックを利用するので、実行環境でのネイティブライブラリの有無に関しては意識する必要はありません。


さて、node-canvas ではサーバーサイドで HTML5 の Canvas を操作するイメージで動的に画像を作ったり、変更したりすることができます。

ブラウザ上でも Canvas は JavaScript で操作することが多いと思いますが、以下のようにほぼ同じような操作で扱うことができます:
var fs = require( 'fs' );

var Canvas = require( 'canvas' ),  //. ここでライブラリ読み込み
    Image = Canvas.Image;          //. 画像生成用オブジェクト

  :

//. public という空ディレクトリをあらかじめ用意しておく(そこに画像を作る)
app.use( express.static( __dirname + '/public' ) );

app.get( '/xxx', function( req, res ){
  //. /xxx に GET アクセスがあったら、その場で画像ファイル xxx.png を生成して、画像にリダイレクトする
  var img = new Image;
  var canvas = new Canvas( 300, 300 );
  var ctx = canvas.getContext( '2d' );

  //. 斜めに赤い線が1本引いてあるだけの画像を作る
  ctx.beginPath();
  ctx.moveTo( 100, 100 );
  ctx.lineTo( 200, 200 );
  ctx.strokeStyle = 'red';
  ctx.stroke();

  //. 画像を Base64 エンコードで取り出して、デコードして、xxx.png という名前で保存する
  var b64 = canvas.toDataURL().split( ',' )[1];
  var buf = new Buffer( b64, 'base64' );
  fs.writeFile( __dirname + '/public/xxx.png', buf, function(){
    res.redirect( '/xxx.png' ); //. 作った画像にリダイレクト
  });
});

上記は僕が作ったサンプルコードの一部を多少変更したものです。Node.js で実行して、/xxx というパスに GET アクセスがあると動的に /xxx.png という画像ファイルを作って(そこにリダイレクトして)表示する、というものです。実際に画像を描いたり作ったりしているのは赤字の部分なのですが、ほぼそのままブラウザ内の JavaScript でも動く記法になっています。

普段から HTML5 の Canvas を使っている人であれば、そのスキルをそのままサーバーサイドで動的に画像を作る技術に応用できると思います。とても便利。

 

IBM InterConnect 2017 の期間中に IBM Bluemix Platform にドイツリージョン(eu-de)が追加されました。記念に早速ランタイムアプリを1つデプロイして公開してみました:
http://spen.eu-de.mybluemix.net/


このアプリはスマホ用(正確にはジャイロセンサーを搭載したスマホ用)なので、試しに使ってみる場合は上記 URL にスマホのブラウザでアクセスしてみてください。以下のような画面が表示されます:
IMG_0430


画面の下半分あたりを指でタップし、離さずにそのまま空中でスマホを振って、文字等を一筆書で書いてみてください。書き終わったらタップした指を離してください:
IMG_0430


指でタップしていた間にスマホの先端が動いた軌跡が画面内に表示されます。また画面上部の表にはタップしていた間のスマホの左右(LR)や前後(FB)の動きが数値として表示されます(ちなみに DIR は向いている方向角で、今回の軌跡描画では使っていません):
IMG_0431


これだけのアプリですが、全て1つの HTML だけで実現しています。スマホの動きは JavaScript でジャイロセンサーにアクセスしてその値を取得し、軌跡の描画には HTML5 の Canvas を利用しています。また HTML 自体では Canvas は非表示としており、画面に表示されているのはこの Canvas を描き終えたタイミングで動的に画像データを生成して、その画像を <img> タグで動的に表示しています。

スマホのジャイロデータを JavaScript だけで取得するとか、Canvas データから画像データを生成するとか、それなりに凝った処理を行っているこの HTML を Github で公開しました:
https://github.com/dotnsf/SPen/


MIT ライセンスで公開しています。勉強目的なり、取得データを使って別の処理を行うよう改造するなり、いろんな応用はできると思うので、よかったら遊んでみてください。

このページのトップヘ