AWS Lambda を使って LGTM 画像を生成する lambda-lgtm

昨日プロダクトで LT 大会があって,そこで発表した資料 + 詳細をまとめてみた.

一言で言うと,3時間で AWS Lambda を使って LGTM 画像を生成する lambda-lgtm を作ってみたって話で,コードは以下に Push してある.

LT 資料

(公開用に少し修正してます)

GraphicsMagick を使った

画像に文字を乗せるだけなら ImageMagick を使って convertannotate すればうまくできるんだけど,AWS Lambda での実装を考えた場合に stdout にコールバックする方法がわからなくて断念した.本当はできるんだと思うんだけど,はじめて Node.js 書いたから単なるスキル不足な感じ.

そこで ImageMagick から GraphicsMagick に乗り換えて実装した.GraphicsMagick から ImageMagick を互換モードで使うことができるので代替することができるし,AWS Lambda のドキュメントなどを見てると gm を使ってる例があって,もしかしたら ImageMagick より GraphicsMagick の方が推奨なのかなと思ったりした.

スニペットだとこんな感じ.

var contentType = data.ContentType;
  var extension = contentType.split('/').pop();
  gm(data.Body)
    .options({ imageMagick: true })
    .resize(480, 269)
    .fill("#81BD27")
    .drawText(200, 250, 'LGTM')
    .font('/usr/share/fonts/dejavu/DejaVuSans.ttf')
    .fontSize(40)

Amazon Linux でフォントファイルを探す

上のスニペットにもある通り,フォントファイルを指定しないと文字が乗らないことがわかったため,Amazon Linux におけるフォントファイルを探してみた.なんとまぁ,AWS Lambda では通常の Linux のコマンドも実行できてしまうため,フォントディレクトリを ls するだけでファイルの存在を確認することができる.

結果を見ると dejavu っていうフォントが使えそうだったので使った.

exports.handler = function(event, context) {
  var exec = require('child_process').exec;

  var cmd = 'find /usr/share/fonts -name "*.ttf"';
  var child = exec(cmd, function(error, stdout, stderr) {
    if (!error) {
      console.log('standard out: ' + stdout);
      console.log('standard error: ' + stderr);
      context.done();
    } else {
      console.log("error code: " + err.code + "err: " + err);
      context.done(err,'lambda');
    }
  });
};
START RequestId: fe93d7b9-f273-11e4-aade-75bdc1d200e5
2015-05-04T15:41:14.674Z  fe93d7b9-f273-11e4-aade-75bdc1d200e5    standard out: /usr/share/fonts/dejavu/DejaVuSansCondensed.ttf
/usr/share/fonts/dejavu/DejaVuSerif-Bold.ttf
/usr/share/fonts/dejavu/DejaVuSansCondensed-Bold.ttf
/usr/share/fonts/dejavu/DejaVuSerif-BoldItalic.ttf
/usr/share/fonts/dejavu/DejaVuSerifCondensed.ttf
/usr/share/fonts/dejavu/DejaVuSansCondensed-Oblique.ttf
/usr/share/fonts/dejavu/DejaVuSerifCondensed-BoldItalic.ttf
/usr/share/fonts/dejavu/DejaVuSansCondensed-BoldOblique.ttf
/usr/share/fonts/dejavu/DejaVuSerifCondensed-Bold.ttf
/usr/share/fonts/dejavu/DejaVuSans-Oblique.ttf
/usr/share/fonts/dejavu/DejaVuSans.ttf
/usr/share/fonts/dejavu/DejaVuSerif-Italic.ttf
/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf
/usr/share/fonts/dejavu/DejaVuSerifCondensed-Italic.ttf
/usr/share/fonts/dejavu/DejaVuSans-ExtraLight.ttf
/usr/share/fonts/dejavu/DejaVuSerif.ttf
/usr/share/fonts/dejavu/DejaVuSans-BoldOblique.ttf

2015-05-04T15:41:14.675Z  fe93d7b9-f273-11e4-aade-75bdc1d200e5    standard error: 
2015-05-04T15:41:14.675Z  fe93d7b9-f273-11e4-aade-75bdc1d200e5    result: null
END RequestId: fe93d7b9-f273-11e4-aade-75bdc1d200e5
REPORT RequestId: fe93d7b9-f273-11e4-aade-75bdc1d200e5  Duration: 261.13 ms Billed Duration: 300 ms    Memory Size: 192 MB    Max Memory Used: 10 MB 

gm.fontSize() が効かないのはなぜ?

ここは自分で解決できなかった.資料に貼ってる LGTM 画像を見てもらえればわかる通り,フォントサイズの指定が効いていなくて,非常に小さくなってしまっている.なお,ローカルで Node.js を動かすとフォントサイズが反映されるので AWS Lambda 上での問題なのかなと予想はしてるけど,わかる人教えてください!!!

AWS Lambda を使ってみて良かったところ

  • 無料枠で十分検証できる(ただし S3 などはコストが少し掛かる)
  • 管理コンソール上でコードを書いて,サンプルイベントを発火させることで繰り返し試行錯誤することができる(ホント便利!)
  • できることに制限がなく Node.js で書ければ何でもできてしまう感があって自由度が高い

S3 のイベント

今回は Put を使ったけど Post も使えそうな感じがする.S3 のバケットで簡単に設定ができて,悩む場面が全く無いところも助かる.

  • Put
  • Post
  • Copy
  • CompleteMultiPartUpload

f:id:kakku22:20150506211811p:plain

まとめ

少し使ってみたけど,AWS Lambda の拡張性や自由度の高さから未来感のあるコンピューティングサービスだなと感じた.

LGTM 画像に関してはフォントサイズが小さくて微妙な感じだけど,動作としては問題なく,サクッと作れた.

あとは S3 に画像を置く部分をアプリ化したり,他から Sync するようなことができれば,もっと面白そうなことができそう.

おまけ

酔っ払いながら LT してますw

f:id:kakku22:20150508225831j:plain

関連エントリー