Gojabako ZoneKei Ito

ブログ記事の画像を生成する

に公開

SNSでURLをシェアしたときに表示されるページ情報に画像があるとかっこいいのでできるようにしました。

画像表示のテストhttps://t.co/YRGuXME8dI

— Kei Ito (@gjbkz) February 11, 2022

これを書いている時点の記事画像はこのような感じです。右下の枠にはURLのQRコードを表示する予定です。

生成した画像の例(旧版)#img1
生成した画像の例(旧版)

2/12追記: タイトルが目立つようにデザインを修正しました。

生成した画像の例#img2
生成した画像の例

## 画像の生成方法

画像に含めている情報は以下の通りです。

  1. 記事のタイトル
  2. 記事の作成日と更新日
  3. 記事のURL

これらはページのmetaタグを入れるためにこのような形でデータを用意してありました。

/src/pageList.ts#L3-L10#code1
1export interface PageData {2 pathname: string;3 title: string;4 filePath: string;5 publishedAt: string;6 updatedAt: string;7 commitCount: number;8}

これをnode-canvasでPNG出力します。

## 背景の影

画像の枠についている影はStackBlurを使っています。

/packages/page/generatePageImage.ts#L88-L94#code2
1/** 影の四角を描いて */2ctx.fillStyle = 'rgba(0,0,0,0.2)';3drawRoundedRect(ctx, x + 2, y + 2, w, h, borderRadius);4ctx.fill();5/** まるごとぼかして */6stackBlur.canvasRGB(ctx.canvas, 0, 0, width, height, blurRadius);7/** 枠を書く */8ctx.fillStyle = colors.background;9drawRoundedRect(ctx, x - 1, y - 1, w, h, borderRadius);10ctx.fill();

## 改行位置の調整

フォントサイズが60pxだと日本語で17文字で横幅いっぱいになります。文字を小さくするのは読みにくいので長いタイトルの場合は改行することにしたのですが、看板のようなものなのでたとえ
ばこのような位置で改
行されると格好が悪いです。

文節を切らないように改行位置を決めればいい具合になります。今回はKuromojiを使って以下のような禁則処理を実装をしました。

  1. 助詞、助動詞の前では改行しない
  2. 開き括弧の後ろでは改行しない
  3. 閉じ括弧の前では改行しない
  4. 句読点の前では改行しない
  5. 数字の後ろでは改行しない("10cm"など単位を想定しています)

例えば「今日の8時からNext.jsの話をします」の場合は以下のスラッシュの位置でのみ改行します。
「今日の/8時から/Next.jsの/話を/します」

改行のある場合の例#img3
改行のある場合の例

## はみ出し対策

タイトルが長いとはみ出してしまうので行がはみ出す場合はフォントを小さくしてリトライするようにしました。QRコード部分に重ならないように改行位置も調整しています。

長いタイトルと長いURLの場合#img4
長いタイトルと長いURLの場合

## 課題

QRコード表示を実装して右下の謎の枠をなんとかしないといけません。