手軽にパラパラ漫画みたいなgifアニメーションをつくれるツールを作ってる

f:id:razokulover:20170223151017g:plain

このツールで自作したビームを出す棒人間のgif。製作時間2,3分。

背景

3年くらい前からGIFMAGAZINEというwebサービスを作ったりしている。

ここでは巷でよく見かける衝撃映像とか猫の癒し画像がアップロードされたりすることもあるのだが、意外にも映像作家の方の作品やドット絵職人みたいな方が作ったアート寄りの作品が結構アップロードされる。

いつもは見ているだけなのだけど、この前作った低画質画像メーカーで遊んでいるうちにオリジナルで何か作ってみたいという気持ちになった。

ただ静止画の絵ならまだしも、アニメーションとなると非常にハードルが高い。

ググるAdobe製品でちょちょいっやるとできるで〜みたいな記事もヒットするのだけど、残念なことに当方PhotoshopをはじめとするAdobe製品があまり使えないので厳しい。

また、「若者よ、EasyToonというものがあってな…」という意見もあるのだがあれMac版ないよね…(wineで動かすとか…それならAdobe製品覚えるわ)

そもそも絵も全然書けない人間がちょいっとアニメーション作りたいだけなのでツールなんて最低限の機能があれば良いよね。

という諸々の事情があり、現在

というものを作っている(まだ使い心地や対応環境が未熟なのでβにしてる)。

基本機能

最低限満たすべき基本的な要件としては下記の通り。

  • WEBでアクセスできる
    • アプリのダウンロードとかしたくない
  • 絵が書ける
    • 色とかペンの細さを変えたり消したりできる
  • 書いた絵(フレーム)を合成してgifアニメにできる
  • フレームの透かしができる

これが満たされれば、とりあえず棒人間を少しずつずらしながら書いていけばパラパラ漫画みたいなアニメーションは作れるはず。

そんで最初にできたのがこんな感じ。

f:id:razokulover:20170223131740g:plain

その後、実際に書いたりしていくうちに画力がなさすぎて絵が書けないことがネックになるとわかった。

なので下絵(見本)を透かしでいれたいということで、

  • 下絵の追加

の機能も実装してみた。

こんな感じ。アップロードした画像から主線などを抽出して透かしとして表示する。

あとは不慮の事故を起こしてブラウザが死んだときに辛かったので「プロジェクトの保存」の機能も追加することにした。

で、現状こんな感じになってる。

f:id:razokulover:20170223132525g:plain

中でもプロジェクトの保存ができるようになったのがかなり便利で、絵を集中して書いて疲れたら保存してまた明日みたいなことができる。

この機能がないとすべて書ききるまでPCが閉じれないしブラウザが落ちたら最初からやり直しだし精神衛生上悪すぎる。

ただ、プロジェクトの保存についてはユーザーの紐付けが必要になるのでログインしてないと使えない。これは仕方ないので我慢。

また、スマホでは使えないようになってる。理由は簡単でWEBのお絵かきツールでスマホで使いやすい作りにすることは無理だろうと判断したから。UI設計がPCとは違いすぎるし、そもそもスマホでツールなら絶対アプリだろう。

あとPCで作れれば自分としては十分だったのもある。

技術的なこと

以下は技術的なとこ。興味ない人は飛ばしてね。

実際のところ自分はJS力がかなりぴよぴよなのでモダンな作りとかにできてない。

こういうツール系はReactとか使えば構造的に作れるんだろうけど。

とはいえcanvasに書いたり消したりはさすがにコーディングできるのでそこを除いて、

実装時には下記の3つの課題があった。

①どうやって下絵の抽出をするか

下絵の抽出はCanny法を利用することにした。

Canny法はコンピュータービジョンでいう特徴抽出の手法。輪郭などのエッジを検出する他の手法の中ではかなり精度が良い。

昔の記事だがここで砕けた言葉で手順を解説してるので読むとわかりやすいと思う。

ざっくりいうと、ノイズを減らして、フィルタをかけてエッジをみつけて、閾値から最終的にエッジかどうかを判定する、という感じ。

肝は閾値を2つ設定してエッジを判断するとこかなと思うのだけど、これを手動で決めさせるのはさすがにだるいのでここではmin=50,max=150で一律判定するようにしてる。

この閾値を動的に変えて遊びたい人のための場所も作っておいたので遊んでみてくれ。

いらすとやのサーバルはこんなにくっきり抽出できる。

f:id:razokulover:20170223141512p:plain

②どうやってプロジェクトの保存をするか

プロジェクトの保存はこれまた結構大変。

パッケージ化してPC用のアプリにすれば、ローカルにファイルをおけばいいだけなので楽なのだけどwebで完結となると話は別だ。

webではローカルファイルとしておけない分、フレームとフレーム情報をどこかにアップロードして保存しておかないといけない。

フレームの情報はシリアライズしてDBに突っ込めばいいかもしれない。問題はフレームのほうだ。

フレームはアニメーションの長さにもよるがふつうに数十枚になる。

これをひとつひとつアップロードしていたのではさすがに通信が発生しすぎだし、プロジェクトの編集時もフレーム数分の読み込み通信が発生してしまうのでよくない。静止画とはいえ複数枚だとユーザーの帯域も使ってしまうし。。

ということで方針としては、

  • クライアント側でフレームをzipにまとめてアップロード
  • クライアント側でzipを解凍してcanvasに書き出してフレーム化

を行うようにした。

幸いにもjsでzip化するにはJSZipという便利ライブラリがあり、これを使うとさくっとできる。

過去にはPixivさんがJSZipによるファイル一括DLというエントリを書いていてくれたりするので読んでみると良いかもしれない。

③どうやってgifとして書き出すか

複数のcanvasをまとめてgifアニメにするのに一番手軽なのはgif.jsを使うことだ。

これを使うとこんな簡単にgifが作成できる。

var gif = new GIF({
  workers: 2,
  quality: 10
});

gif.addFrame(canvasElement1, {delay: 200});
gif.addFrame(canvasElement2, {delay: 200});
gif.addFrame(canvasElement3, {delay: 200});

gif.on('finished', function(blob) {
  window.open(URL.createObjectURL(blob));
});

gif.render();

canvas(もしくはimg)からgifアニメを作るなら大抵の用途はこれで満たせる。

ただ、このライブラリは透過をうまく扱えない。

なので透過も実現したいならomggifを使うといいかも。これはこれでドキュメントがないしもうメンテされてないので厳しいんだけど。

ただ、自分でもgif.jsのcanvasをフレームとした透過処理がうまく機能しない理由がわかっていなくて気持ち悪いので、あとでちゃんとコード追って原因をつきとめたいところ。

今後

まだ使い勝手は微妙なところも多いし、基本Chromeでの動作しか確認してないのでバグが結構ある気がする。

その辺の安定性を高めたり、複雑にならない程度に必要な機能をつけていきたい。

あと絵がうまくなりたい。

まとめ

  • パラパラ漫画みたいなgifアニメを作成できるツールを作ってる
  • webから使えるようにするために色々苦労がある
  • 絵がうまくなりたい

子供の頃はよく教科書にボールが行ったりきたりするパラパラ漫画を書いたものだ。

うまくできると友達に見せてはよく承認欲求を満たしていたような気がする。

何より自分で作ったものが動くという成功体験は何ものにも代えがたい。

教科書がiPadになってしまったらあの体験ができなくてもったいないなとか思いつつ、でも教科書を何十冊も持ち歩くのはクレバーじゃないのでそういう意味ではこういうwebで手軽にパラパラ漫画みたいなアニメーションを作れるといいのかもしれない。

別にこのツールで自分が儲かったりはしないんだけども、エンジニアである以上、そういう誰かの何かになるものを作っていたい。

おまけ

このツールは、GIFMAGAZINEの機能の一部として作られている。

GIFMAGAZINEでは何かを描いたり制作しているクリエーターのためになるものなら自由につくってよいルールがあり、先日公開した低画質画像メーカーもこの一環で作られた。

最近ではエンジニアの採用もはじめたので、もしこういった開発に興味があるインターネット好きな人がいたら@razokuloverまでご連絡ください