目的
ユーザーによって異なる画像を生成し、OGPに設定する。
それぞれのやり方のメリット・デメリット
画像生成には下記2つやり方がある。
- クライアントサイドでhtml2canvasを用いて画像生成
- imagemagickでサーバサイドで画像生成
もしアプリ展開してクライアントサイドが複数になる場合はサーバサイドで一括して処理したほうが工数も減り良さそう。html2canvasのほうがcssなどでレイアウトをいじれるので細かい調整は効きそう。
imagemagicのメリットデメリット
メリット
- サーバサイド側で処理したらユーザー側の環境の影響受けなさそう。
デメリット
- 日本語だと折返しの処理を自分で書かないといけないのが面倒だし難しい
- 複数フォントを読み込めない
- 色付きの絵文字フォントを扱えない
html2canvasのメリットデメリット
メリット
- imagemagicよりはデザイン調整楽そう
デメリット
- 対応していないcssがあるので注意
- ユーザーのブラウザによってデザインが微妙に変わる
html2canvasを用いて画像生成
全体設計
- html2canvasで画像を生成
- javascriptからbase64→blobに変換
- hidden_fieldでcarriwave経由でサーバに送る
そもそもcanvasとは?
ブラウザ上で図を書くための仕様でhtml5で採用されている。タグでhtmlのスペースを規定してその中でjavascriptを用いて描画する。
html2canvasの導入
ドキュメント
http://html2canvas.hertzen.com/documentation
npmで導入する。詳しい導入方法は上記。
html2canvasで任意のDOMを画像に
//ロードされた際の処理として実施:
window.onload = function(){
//HTML内に画像を表示
html2canvas(document.getElementById("target"),{
onrendered: function(canvas){
//imgタグのsrcの中に、html2canvasがレンダリングした画像を指定する。
var imgData = canvas.toDataURL();
document.getElementById("result").src = imgData;
}
});
}
引用:https://qiita.com/youwht/items/8b681a856f59aa82d671
html2canvasは#targetに指定したidをキャプチャする。
appendChildについて
appendChildは、特定の親要素の中に要素を追加するためのメソッドです。javascriptで使われるものでjqueryだとappendのみ
「【JavaScript入門】appendと何が違う?appendChild徹底解説」
引用:https://www.sejuku.net/blog/49970
画像をbase64→blobに変換
textform経由で送信
生成した画像を保存
rails+carrierwaveで画像保存する方法は上記。
ブラウザに表示させたくない場合
隠しDOMで別に作っておいてoverflow:hiddenで隠す方法があるらしい(未確認。誰か教えて)
retina対応
html2canvasのデフォルト設定では、生成された画像をRetinaディスプレイで見たときに、画質が荒くなってしまいます。 公式対応は現状されていないのですが、なんと有志の手によってRetina対応が可能となりました。 https://github.com/niklasvh/html2canvas/pull/1087
ファイルを一部書き換える手間は生じますが、その後はdpi, scaleオプションを設定することで、生成された画像を綺麗に表示することが可能となります。 ただし、サイズや画質を上げると、その分レンダリング処理に時間がかかり、また上記の描画領域制限に引っかかる可能性があるので、注意が必要です。
引用:https://techblog.kayac.com/html2canvas
puppeteerを使う(調査中)
svgから生成
「Vue.jsとFirebaseでOGP画像生成系のサービスを爆速で作ろう」を実際に作ってみる」
https://qiita.com/kanye__east/items/6cbcdc8fe5103084c737
この記事ではsvgに文字を出して画像化している。ただこのやり方だとおそらく改行ができない。