node.jsで、サーバサイドで画像を加工するライブラリとかないかなーと探していたら、HTML5 Canvasの実装がされたnode-canvasっていうのがあって、昔、http://labo.dtpwiki.jp/kousei/ (GitHubはこちら)ていう文字校正サイトを作るときにWebブラウザ側ではあるがHTML5 Canvasを使ったし、あれならまあまあ使えるなあと思い、これをRaspberry Piでやってみます。
割と依存ライブラリが多いので、特にRaspberry Piに限定したインストール情報が有益かなあと思い、まとめました。
動作環境
極端な機種依存はないと思いますが、当方では以下の環境で動作確認しています。
- Raspberry Pi B+(1CPU、512MB RAM)
- NOOBS_v1_4_1.zip を使ってインストールしたRaspbian GNU/Linux 7
- node.jsはnode-armから入手できるv0.12系(こっちでインストール例を書いた)
- apt-getするのでネットワーク接続が必要
- piユーザでログインできること、piユーザがsudoでroot使えること(Raspbianのデフォルト設定)
インストール
apt-getでupdateしておきます。特にapt-get upgradeする必要はない。
pi@raspberrypi ~ $ sudo apt-get update
node-canvasを入れる時に必要とされるライブラリをapt-getで入れておきます。
pi@raspberrypi ~ $ sudo apt-get install libcairo2-dev libpango1.0-dev libjpeg8-dev libgif-dev
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下の特別パッケージがインストールされます:
gir1.2-freedesktop gir1.2-pango-1.0 libcairo-script-interpreter2 libelfg0 libexpat1-dev
libfontconfig1-dev libglib2.0-bin libglib2.0-dev libharfbuzz-dev libice-dev liblzo2-2
libpcre3-dev libpcrecpp0 libpixman-1-dev libpthread-stubs0 libpthread-stubs0-dev libsm-dev
libx11-dev libx11-doc libxau-dev libxcb-render0-dev libxcb-shm0-dev libxcb1-dev libxdmcp-dev
libxext-dev libxft-dev libxrender-dev x11proto-core-dev x11proto-input-dev x11proto-kb-dev
x11proto-render-dev x11proto-xext-dev xorg-sgml-doctools xtrans-dev
提案パッケージ:
libcairo2-doc libglib2.0-doc libice-doc libpango1.0-doc imagemagick libsm-doc libxcb-doc
libxext-doc
以下のパッケージが新たにインストールされます:
gir1.2-freedesktop gir1.2-pango-1.0 libcairo-script-interpreter2 libcairo2-dev libelfg0
libexpat1-dev libfontconfig1-dev libgif-dev libglib2.0-bin libglib2.0-dev libharfbuzz-dev
libice-dev libjpeg8-dev liblzo2-2 libpango1.0-dev libpcre3-dev libpcrecpp0 libpixman-1-dev
libpthread-stubs0 libpthread-stubs0-dev libsm-dev libx11-dev libx11-doc libxau-dev
libxcb-render0-dev libxcb-shm0-dev libxcb1-dev libxdmcp-dev libxext-dev libxft-dev
libxrender-dev x11proto-core-dev x11proto-input-dev x11proto-kb-dev x11proto-render-dev
x11proto-xext-dev xorg-sgml-doctools xtrans-dev
アップグレード: 0 個、新規インストール: 38 個、削除: 0 個、保留: 25 個。
14.3 MB 中 0 B のアーカイブを取得する必要があります。
この操作後に追加で 38.4 MB のディスク容量が消費されます。
続行しますか [Y/n]? y
割とたくさんライブラリが必要です。
apt-getによる必要なパッケージのインストールが終わったら、プログラムを作りたいディレクトリを作り、その中に入って、npmでnode-canvasを入れます。
pi@raspberrypi ~ $ mkdir test
pi@raspberrypi ~ $ cd $_
pi@raspberrypi ~/test $ npm install canvas
-
> canvas@1.2.7 install /home/pi/test/node_modules/canvas
> node-gyp rebuild
make: Entering directory '/home/pi/test/node_modules/canvas/build'
SOLINK_MODULE(target) Release/obj.target/canvas-postbuild.node
COPY Release/canvas-postbuild.node
CXX(target) Release/obj.target/canvas/src/Canvas.o
CXX(target) Release/obj.target/canvas/src/CanvasGradient.o
CXX(target) Release/obj.target/canvas/src/CanvasPattern.o
CXX(target) Release/obj.target/canvas/src/CanvasRenderingContext2d.o
../src/CanvasRenderingContext2d.cc: In member function ‘void Context2d::shadow(void (*)(cairo_t*))’:
../src/CanvasRenderingContext2d.cc:379:22: warning: unused variable ‘surface’ [-Wunused-variable]
CXX(target) Release/obj.target/canvas/src/color.o
CXX(target) Release/obj.target/canvas/src/Image.o
CXX(target) Release/obj.target/canvas/src/ImageData.o
CXX(target) Release/obj.target/canvas/src/init.o
CXX(target) Release/obj.target/canvas/src/PixelArray.o
CXX(target) Release/obj.target/canvas/src/FontFace.o
SOLINK_MODULE(target) Release/obj.target/canvas.node
COPY Release/canvas.node
make: Leaving directory '/home/pi/test/node_modules/canvas/build'
canvas@1.2.7 node_modules/canvas
└── nan@1.9.0
pi@raspberrypi ~/test $
サンプルプログラム
今回作ったプログラムはこれ。
'use strict';
// kanji.js:
// node.jsでテキストバナーを表示します。
// use libs;
var Canvas = require('canvas');
// Const
var WIDTH = 80;
var THRESHOLD = 100;
// 描画
var Image = Canvas.Image;
var canvas = new Canvas(WIDTH, 16);
var ctx = canvas.getContext('2d');
ctx.font = '16px Sans-serif';
ctx.fillText("漢字ROM", 0, 11);
ctx.stroke();
// ピクセル走査
var imageData = ctx.getImageData(0, 0, WIDTH, 16);
for (var y = 0; y < 16; y++ ) {
var text = '';
for (var x = 0; x < WIDTH; x++) {
// RGBa
text += (imageData.data[(x + y * WIDTH) * 4 + 3] > THRESHOLD ? '0' : ' ');
}
console.log(text);
}
実行結果
実行する。
pi@raspberrypi ~/test $ node kanji.js
00 00 00 00
00 0000000000 0000000000000 0000 0000 0 0
0 000000000 00000000000000 0000000 00000000 00 000
0 0 00 00 00 00 00 00 000 0000
00 000000000 00000000 00 00 00 00 000 0000
00 00 00 0 000 00 00 00 00 0 0 0 00
0 000000000 000 00 00 0 0 0 00 00 00
00 00 0000000 0 0 0 00 00 00
000000000 00000000000000 00 00 0 00 0 0 0 00
00 00000000 00000000000000 00 00 00 00 0 0000 00
0000000000000 00 00 0 00 00 0 000 00
0 0000000000 00 00 00 000 000 0 00 00
00 00000 00 00 00 000000 0 00 00
0 000 0000 000
0 0 00
pi@raspberrypi ~/test $
なお、node-canvasのGitHubにあるサンプルプログラムも当然動く。
未解決問題
文字描画のアンチエイリアス効かせない方法って、ないものかな。
=>ドキュメントに書いてあった。
ctx.antialias = 'none';
出力はこうなる。
0 0 0 00
0000000000000 00000000000000 00
0 0 0 00000000000000 0000000 000000 00 00
0 0 00 00 00 00 00 00 00 00
0 000000000 00000000 00 00 00 00 000 000
00 00 0 0 00 00 00 0 0 000 000
0 000000000 00 00 0 0 0 000 000
0 00 000000 0 0 0000 0 0
000000000 00000000000000 00 0 0 0 0 0 0 0
0 0 00000000000000 00 00 00 00 0 0000 0
0000000000000 00 00 0 00 00 0 000 0
0 00 00 00 00 00 00 0 00 0
00 00000 00 00 00 000000 0 00 0
0 0000 0000 0000
00
Mの文字の縦棒あたりがヒンティング効いているっぽくなった。
追記
こちらで、フォントファイルを指定した場合の描画をやってみました。
pi@raspberrypi ~/test3 $ node kanji.js
0 0 00
0 0000000000 00000000000000 000000 0000 0 0
0 0 0 00 00 0 000 00 00 00 00
0000000000 00 00 0 0 00 00 00 00
0 00 00 00 00000000000000 0 0 0 0 000 000
00 00 00 00 00 0 0 00 00 000 000
000000000000 00 0 0 00 00 0 0 0 0
00 0 000000 00 00 0 0 0 0
0000000000 00000000000000 0 00 00 00 0 00 0
0 00 00000000000000 0 0 0 0 0 00 0
000000000000 0 0 00 00 00 0 0
0 0000 0 0 0 00 00 0 0
0 00 00 0 0 0 000000 0 0
0 00 00 00000
pi@raspberrypi ~/test3 $
ローマ字の字形が整っているように見える。