やりたいこと
- 画像上の特定範囲の上下左右中心にテキストを描画
- リアルタイムで編集
- 編集後の画像をコピー、ダウンロード (本記事では含まない)
いわゆる吹き出し画像向けの文字画像ジェネレーター
作ってみた (デモ)
フロントのフレームワークはVueとVuetifyを利用しました。
See the Pen sentence-image-generator by icchi (@icchi) on CodePen.
ポイント
Canvasで描画
描画するだけであればvueと親和性の高いSVGのほうが個人的には扱いやすいと思います。ただし、今回は描画画像をBase64形式でコピー、またはダウンロードしたいという条件があり、それも含めて考慮するとSVGよりもCanvasの方が実装工数が低いと判断しました。
canvasであれば下記のようにたった1行のコードでcanvasオブジェクトからbase64形式の画像を取得可能です。
canvas.toDataURL("image/png");
// canvas: 次のような感じで取得できるcanvasオブジェクト
// const canvas = document.getElementById("canvas");
SVGでもHeadless Chromeを利用した以下のようなnode moduleで変換は可能ですが、canvasに比べ利用ライブラリの規模は大きくなってしまいます。
https://www.npmjs.com/package/convert-svg-to-png
テキスト描画範囲の座標指定
吹き出し(特定範囲)内にテキストを描画するために、その範囲を定義しておく必要があります。
今回は以下のように実装しました。
左上を原点として、範囲の左上、右下の座標を原点からの割合(小数)で定義しています。
textareaRate: { // 画像中のテキスト表示エリアの左上・右下座標(左上基準)
start: {
x: 0.26,
y: 0.1
},
end: {
x: 0.72,
y: 0.34
}
}
テキスト描画における基準点の位置
canvasにテキストを入力する場合、その指定座標に対する描画位置に若干クセがあります。
以下の画像がわかりやすいですが、デフォルトの設定だと指定座標が文字の左下に位置するように描画されます。
https://stackoverflow.com/questions/11120392/android-center-text-on-canvas
今回は吹き出し範囲の上下左右中心にテキストを描画したいため、指定座標がテキストの中心に位置するようにしてあげる必要があります。canvasのcontext設定項目の中には指定座標に対するテキスト位置のオプションが用意されているので、それらを以下のように指定します。
// get context
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
// set align center(horizontal/vertical)
context.textAlign = "center";
context.textBaseline = "middle";
改善点
自動フォントサイズ調整
例えばAPIライクなサービスを想定して完全な自動生成を実現するに、吹き出し範囲からテキストがはみ出さないよう描画する量に合わせてフォントサイズを調節