はじめに
おそらく、やい、確実にNode.js系のライブラリを使って作成した方が簡単だと思います
Goでももっと簡単に直感的に作る方法はあると思いますが
リポジトリ
まず、はじめにFigmaでレイアウトを決める
- 1200x630の画像を作成します(なんか1200x630が推奨サイズらしいから)
- ほか色々とレイアウトを決めましょう
- フォントの種類・文字の太さ・文字を折り返す長さを決める
- 今回は910px以上の文字サイズになったら折り返すようにしました
- タイトル:
Noto Sans Japanese - Midumu
を使っています - ユーザー名:
Noto Sans Japanese - Regular
を使っています
↓ できたものがこちらになります
FigmaのデザインをGoで再現する
Figma上でCSSの情報を見ることができます
背景色の情報をGoで表現する
これがFigmaから取得した背景色の色です。こちらは透明色(Alpha)を使っていますが、RGBAよりRGB表現の画像の方が使いやすいのでRGBAをRGBに変換しましょう
background: linear-gradient(105deg, #FFC5C1 0%, rgba(217, 140, 218, 0.29) 25%, rgba(255, 246, 167, 0.68) 69.43%, rgba(122, 239, 255, 0.37) 100%);
Alphaを使っている場合は、こう言ったツールを使いましょう
// 1200x630の画像を生成
width := 1200
height := 630
dc := gg.NewContext(width, height)
// 左上から右下に向かってグラデーション
grad := gg.NewLinearGradient(0, 0, float64(width), float64(height))
grad.AddColorStop(0, color.RGBA{255, 197, 193, 255})
grad.AddColorStop(0.25, color.RGBA{244, 222, 244, 255})
grad.AddColorStop(0.6943, color.RGBA{255, 249, 195, 255})
grad.AddColorStop(1, color.RGBA{206, 249, 255, 255})
dc.SetFillStyle(grad)
// 画像全体の矩形を描画してグラデーションを適用
dc.DrawRectangle(0, 0, float64(width), float64(height))
dc.Fill()
グラデーションの上に白い図形を追加する
Figmaから取得したCSSをもとにPaddingの設定をやりましょう
// 図形のサイズと位置を計算
rectWidth := width - 2*43
rectHeight := height - 2*41
rectX := 43
rectY := 41
// 背景色を設定
dc.SetColor(color.RGBA{255, 255, 255, 255})
dc.DrawRoundedRectangle(float64(rectX), float64(rectY), float64(rectWidth), float64(rectHeight), 16)
dc.Fill()
タイトルを表示する
私はバイナリで動かす前提で作っていますので、embedを使ってフォントを埋め込んでいます
//go:embed embed/NotoSansJP-Medium.otf
var fontTitle []byte
/* 〜〜〜〜〜〜〜〜 中略 〜〜〜〜〜〜〜〜 */
// フォントを読み込む
fontFace, err := opentype.Parse(fontTitle)
if err != nil {
http.Error(w, "Failed to parse font", http.StatusInternalServerError)
return
}
face, err := opentype.NewFace(fontFace, &opentype.FaceOptions{
Size: 64,
DPI: 72,
})
if err != nil {
http.Error(w, "Failed to create font face", http.StatusInternalServerError)
return
}
dc.SetFontFace(face)
// 文字を挿入
dc.SetRGB(0, 0, 0) // 文字色を黒に設定
maxWidth := 910.0
title := "Go言語でOG:imageを作成してみる!!"
formatTitle := ""
tmp := 0.0
for _, word := range title {
fw, _ := dc.MeasureString(string(word))
if tmp+fw > maxWidth {
formatTitle += "\n"
tmp = 0.0
}
formatTitle += string(word)
tmp += fw
}
x := 145.0
y := 175.0
for _, line := range strings.Split(formatTitle, "\n") {
dc.DrawString(line, x, y)
y += 82
}
ユーザー名を追加
上の一緒のことをやるだけなので(ry
サイトなり、好きロゴを入れる(それっぽくなる)
//go:embed embed/logo.png
var logo []byte
/* 〜〜〜〜〜〜〜〜 中略 〜〜〜〜〜〜〜〜 */
// サイトのロゴを挿入
logoImg, _, err := image.Decode(strings.NewReader(string(logo)))
if err != nil {
http.Error(w, "Failed to decode logo image", http.StatusInternalServerError)
return
}
// ロゴのサイズを変更
resizedLogoImg := resize.Resize(0, 150, logoImg, resize.Lanczos3)
// ロゴを挿入
dc.DrawImage(resizedLogoImg, 800, 430)
大体、同じものができました!!(発色が少し違う)
Figmaで作成したやつ | Goで生成したやつ |
---|---|
![]() |
![]() |
最後に
最初でも言ってますが、Goでやることでは無いと思います。
私は趣味でWebサイト作ってまして、OG:imageに対応するためにReactで作っているWebサイトをNext.jsで書き直しています。その流れでOGイメージもNext.jsで作ろうとしたんですが、作るのが難しくて 私がフロント素人なものでGoに逃げました。
私の𝕏(Twitter)はこちらです。エンジニアのフォロワーさんが少ないので、フォローしていただけたら嬉しいです