Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@icchi_h

canvasを使って画像中の特定範囲にテキストを描画する (文字画像ジェネレーター)

やりたいこと

  • 画像上の特定範囲の上下左右中心にテキストを描画
  • リアルタイムで編集
  • 編集後の画像をコピー、ダウンロード (本記事では含まない)

いわゆる吹き出し画像向けの文字画像ジェネレーター

作ってみた (デモ)

フロントのフレームワークは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にテキストを入力する場合、その指定座標に対する描画位置に若干クセがあります。

以下の画像がわかりやすいですが、デフォルトの設定だと指定座標が文字の左下に位置するように描画されます。

WVwFw.png
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ライクなサービスを想定して完全な自動生成を実現するに、吹き出し範囲からテキストがはみ出さないよう描画する量に合わせてフォントサイズを調節

参考文献

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
3
Help us understand the problem. What are the problem?