目的
この note のページのogp画像を以下の仕様で自動生成したい。
結果

OSS
すでにこのサイトでは、画像処理に sharp を使用しているので、ここでも sharp を使用する。
以前は jimp を使用していたが、 sharp の方が扱いやすい上に処理も早かった。
const sharp = require('sharp')
await sharp('ベース画像')
.composite([{ input: タイトル画像 }])
.toFile('出力画像'))
}
sharp は文字を扱えないので、文字を画像化するためにこれを使用する。
text2png() に文字列とオプションを与えると画像バッファを返してくれる。
const text2png = require('text2png')
const options = {
font: '72px NotoSansJP-Bold',
localFontPath: '/fonts/NotoSansJP-Bold.otf',
localFontName: 'NotoSansJP-Bold',
color: '#345',
lineSpacing: 20
}
const titleImage = text2png('タイトル文字列', options)
タイトルの文字列
タイトルが長すぎるとタイトル画像がベース画像よりも大きくなって、sharp に怒られる。
なのでタイトル文字列を以下のように編集する関数を作る
function proofread(str) {
let count = 0
let lineCount = 1
let newStr = ''
const lineLength = 22
for (let i = 0; i < str.length; i++) {
encodeURI(str.charAt(i)).length >= 4 ? (count += 2) : (count += 1)
newStr += str.slice(i, i + 1)
if (count > lineLength) {
if (lineCount === 1) {
newStr += '\n'
count = 0
lineCount += 1
} else {
newStr += '..'
break
}
}
}
return newStr
}
最終形態
const sharp = require('sharp')
const text2png = require('text2png')
const proofread = require('./proofread')
async function createThumImage(title) {
const options = {
font: '72px NotoSansJP-Bold',
localFontPath: '/fonts/NotoSansJP-Bold.otf',
localFontName: 'NotoSansJP-Bold',
color: '#345',
lineSpacing: 20
}
const noteTitle = proofread(title)
const titleImage = text2png(noteTitle, options)
await sharp('ベース画像')
.composite([{ input: titleImage }])
.toFile('出力画像')
}