読者です 読者をやめる 読者になる 読者になる

エロサイトの作り方

2013年11月から勉強しながらエロサイトを作っています。

Node.jsで画像比較を行えるようになるnode-puzzleを使ってみる

PHP界隈では有名らしい、libpuzzleという画像比較ライブラリのNode.js用ネイティブAPIがあったので試してみました。

依存ライブラリを先に入れる

$ brew install libgd libpuzzle

node-puzzleを入れる

$ npm install puzzle
clang: error: no such file or directory: '/opt/local/lib/libgd.dylib'
clang: error: no such file or directory: '/opt/local/lib/libpuzzle.dylib'
make: *** [Release/puzzle.node] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/local/Cellar/node/0.10.20/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:267:23)
gyp ERR! stack     at ChildProcess.EventEmitter.emit (events.js:98:17)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (child_process.js:789:12)
gyp ERR! System Darwin 12.5.0
gyp ERR! command "node" "/usr/local/Cellar/node/0.10.20/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/hentai-kun/node/sandbox/node_modules/puzzle
gyp ERR! node -v v0.10.20
gyp ERR! node-gyp -v v0.10.10
gyp ERR! not ok
npm ERR! weird error 1
npm ERR! not ok code 0

エラーになった。先に入れたlibgdlibpuzzleが見つからないらしい。

しかし、見つからないというよりディレクトリが違うのではないだろうか?

$ find /usr/local/lib -name libpuzzle.dylib
/usr/local/lib/libpuzzle.dylib
$ find /usr/local/lib -name libgd.dylib
/usr/local/lib/libgd.dylib

見つかった。やはり、/opt/local/libじゃなくて/usr/local/libなのでは?

ドキュメントを読んでもわからなかったので、GYPファイルを読む

binding.gyp

"link_settings": { "libraries": [ "/opt/local/lib/libgd.dylib", "/opt/local/lib/libpuzzle.dylib" ], }

直書きだー!

シンボリックリンクで回避

GYPファイルを直して作者にプルリクのが筋なんだろうけど、こわいのでシンボリックリンクで逃げる。

$ sudo mkdir -p /opt/local/lib/
$ sudo chown hentai-kun:staff /opt/local/lib
$ ln -s /usr/local/lib/libgd.dylib /opt/local/lib
$ ln -s /usr/local/lib/libpuzzle.dylib /opt/local/lib
$ ls -l /opt/local/lib
total 16
lrwxr-xr-x  1 hentai-kun  staff  26 Dec  4 20:15 libgd.dylib -> /usr/local/lib/libgd.dylib
lrwxr-xr-x  1 hentai-kun  staff  30 Dec  4 20:15 libpuzzle.dylib -> /usr/local/lib/libpuzzle.dylib

今後の宿題でこわくないプルリクを読もう。

node-puzzleを入れる(リトライ)

$ npm install puzzle

今度は入った。

使ってみる

ソース

puzzle_test.js
var puzzle  = require('puzzle');
var context = puzzle.context();

var file1 = process.argv[2];
var file2 = process.argv[3];
console.log('compare: ', file1, file2);

var startTime = new Date().getTime();
var distance  = context.compare(file1, file2);
var workTime  = new Date().getTime() - startTime;

console.log('distance:', distance);
console.log('workTime:', workTime + 'ms');

実行

$ node puzzle_test.js test1.jpg test2.jpg
compare:  test1.jpg test2.jpg
distance: 0.8943324070975381
workTime: 135ms

distanceは0-1の範囲で0だと完全一致判定のようなので、だいぶ遠いですね。

実際、全く違う画像で試したので、合っているように思います。

大きな画像だとエラーになる

Node.jsのimagamagick-nativeを使ってみるで使った画像で試したらエラーになった。

$ node puzzle_test.js img_01_l.jpg img_02_l.jpg
/Users/hentai-kun/node/sandbox/puzzle_test.js:9
var distance  = context.compare(file1, file2);
                        ^
TypeError: error loading file 1
    at Object.<anonymous> (/Users/hentai-kun/node/sandbox/puzzle_test.js:9:25)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:901:3

これはlibpuzzleの制限なのかな?

不満点

cvecという画像の特徴点を計算した結果を保存できないので、毎回ファイルから計算し直すことになるので効率が悪い。というか、実用的じゃない。

これならPHPで実装したものを呼び出した方が速度的に速い気がする。