ユーザーが入力した俳句からGIF画像を生成しています。
これはサーバーでブラウザ(Chrome)を立ち上げ、そのスクリーンショットを繋げることで生成されています。
###################################################
###################################################
↑こんな感じのGIFが作れます。ぜひ実際にやってみて下さい。
どうやってGIF画像を作るのか、コード付きで解説
今回使用する言語はNodejsです。
まずは適当な空ディレクトリに移動して、以下のコマンドを実行して下さい。
$ npm init -f
$ npm install puppeteer png-js gifencoder
使用する3つのライブラリを簡単に説明します。
まずPuppeteerは、GUIを操作することなく、プログラムからAPIでブラウザ(Chrome)を制御できるNode.jsで作られたライブラリ です。今回はPuppeteerのスクリーンショット機能を利用します。
png-jsはPuppteerで撮ったスクショのPNGデータをNodeで扱うためのライブラリで、gifencoderはpngからGIFを作るためのライブラリです。
次に、index.jsを作成し、次のようにして下さい。一回コピペして頂き、動作を確認するのが良いと思います。
const fs = require('fs');
const puppeteer = require('puppeteer');
const GIFEncoder = require('gifencoder');
const PNG = require('png-js');
function decode(png) {
return new Promise(r => {
png.decode(pixels => r(pixels))
});
}
async function gifAddFrame(page, encoder) {
const pngBuffer = await page.screenshot({clip: {width: 1024, height: 200, x: 0, y: 0}});
const png = new PNG(pngBuffer);
await decode(png).then(pixels => encoder.addFrame(pixels));
}
(async () => {
const browser = await puppeteer.launch({
headless: false, slowMo: 0,
});
const page = await browser.newPage();
page.setViewport({width: 1024, height: 200});
const text = '私は猫になりたい';
const html = `<div id="main" style="font-size: 100px;">${text[0]}</div>`;
await page.setContent(html, {
waitUntil: ['networkidle0']
});
// record gif
var encoder = new GIFEncoder(1024, 200);
encoder.createWriteStream()
.pipe(fs.createWriteStream('test.gif'));
// setting gif encoder
encoder.start();
encoder.setRepeat(0);
encoder.setDelay(150);
encoder.setQuality(10); // default
for (let i = 0; i < 10; i++) {
await gifAddFrame(page, encoder);
await page.evaluate(`document.getElementById("main").innerHTML = '${text.slice(0, i + 1)}'`)
}
// finish encoder, test.gif saved
encoder.finish();
await browser.close();
})();
そして実行します。
$ node index.js
動作が終了すると、test.gif
というファイルが出来ているはずです。
それを開くと、次のような画像が出来ています!
詳しく解説
先ほどのコードを読み解くための解説をします。
全体の流れは
PuppeteerでHTMLをレンダリングさせる(この時、「私は猫になりたい」の、「私」だけをレンダリングします。)
以下ループ
→スクショを撮る
→gifencoderにスクショのデータを読ませる
⇨Puppeteerに、ブラウザでJSを実行するように指示する。
です。最後のJSを実行というのは、
await page.evaluate(`document.getElementById("main").innerHTML = '${text.slice(0, i + 1)}'`)
の部分です。ブラウザが表示するHTMLを変えるようなJSを実行することで、アニメーションを作ることが出来るのです。
あとはコードを読んでもらえると、理解できると思います。
まとめ
「五七五メーカー」を作るにあたり、どうすれば良いか試行錯誤したところ、この形になりました。
GIF生成が出来るようになると、面白いサービスがたくさん出来そうでワクワクしますね。
最後まで読んでいただきありがとうございます。いいね、ストック、コメントをお待ちしております。
それでは、最後に一句。
終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話