AIでサムネイル自動生成の実現方法

AIテキスト

技術検証をしていると、「あとで記事にまとめよう」と思いながら、ついそのまま次の実験に進んでしまいます。AIを触っていると、作業の区切りが見えにくく、気づけば制作ばかり進んで記録が追いつかないことがよくあります。

短期記憶が続いているうちに作業を進めたいという心理もあり、どうしても記事を書く作業は後回しになりがちです。結果として、メモや検証結果だけが溜まっていきます。

そこで、少しでも作業を軽くするため、機械的な工程はできるだけ自動化することにしました。まずはブログ記事のサムネイル作成をAIで自動化する方法を検証してみます。

サムネイル作成プロセス

現在はCanvaを使って手動でサムネイルを作成していますが、作業内容はかなり機械的なものになっています。

  1. Canvaのアイキャッチテンプレートを使用(サイズは 1200×630px)して作業を開始
  2. 記事の要点を ChatGPTで要約
  3. 要約からCanvaの 「マジック生成」 で背景画像を作成、気に入った画像を背景として設定
  4. 文字を読みやすくするため、中央に 黒の半透明の正方形 を配置して明度を調整
  5. フォントは Noto Sans Serif、文字サイズは 56pxで、適宜改行を入れてタイトルを配置する。

作業時間は5〜10分程度ですが、どうしても思考停止のルーチン作業になりがちです。できればこの時間を、クォリティを高める作業に使いたいところです。

技術的構成とツール選定

今回、Windows RTX4070(VRAM 12GB)環境で作業できるレベルのツール構成を考えます。

  • 背景構成やテキスト配置はLLMに考えてもらい、OllamaのAPIを使って呼び出す。
  • ComfyUIをAPIで呼び出し、SDXL系のチェックポイントで背景を描画する。
  • 最後にPython + Pillowで文字を配置する。

ChatGPTやGeminiで同様の指示もできますが、生成された画像は文字や構成に難がある場合が多く調整も困難です。このあたりを対話形式のAIで実施するにはまだハードルがあるようです。

LLMにサムネイルの構造を考えてもらう

現在のワークフローでは、記事を書き終えた後にサムネイルを作成します。まず記事の内容をLLMに入力し、画像生成用のプロンプトを生成します。

今回はPythonから扱いやすいように、Ollama上の qwen3:8b を使ってプロンプトを作成しました。他にgemma3等も試しましたが、クォリティと速度のバランスを考慮してもそれほど差はなく、好みで選んで良いと思います。

例えばこの記事では、次のようなプロンプトが生成されました。

digital workspace with AI neural network visualization,
futuristic technology concept, soft blue and purple gradient,
abstract geometric patterns, clean modern design, 8k, high quality

コードはChatGPTに生成してもらいました、ベースは下記のようなイメージです。

import ollama

article_text = open("article.md", "r", encoding="utf-8").read()

response = ollama.chat(
    model="qwen3:8b",
    messages=[
        {
            "role": "system",
            "content": (
                "あなたは画像生成プロンプトの専門家です。"
                "与えられた記事の内容から、SDXL用の英語プロンプトを生成してください。"
                "背景画像として適切な、抽象的かつ技術的な雰囲気のプロンプトを出力してください。"
            ),
        },
        {"role": "user", "content": f"以下の記事からサムネイル背景用のプロンプトを生成してください:\n\n{article_text}"},
    ],
)

prompt = response["message"]["content"]
print(prompt)

Python + Pillowでサムネイル作成

次に、qwen3:8bを使って記事内容からキーワードを抽出します。タイトルはすでに決まっているため、そのまま利用します。

ブログカードでサムネイルを表示する場合、正方形で中央部を切り抜かれる場合があります。 これを念頭に、画像の中央部に正方形の矩形で明度を落としておき、そこに中心的に文字を配置します。

現状のローカルLLMでは、文字装飾やレイアウトを一から設計させるのはまだ難しいようで、事前にChatGPTでいくつかのデザインパターンを用意しておき、そこにキーワードを埋め込む形で生成します。

文字生成部分のコードのベースは下記のようになります。

from PIL import Image, ImageDraw, ImageFont, ImageFilter
import json

# --- 設定 ---
IMG_WIDTH, IMG_HEIGHT = 1200, 630
SQUARE_SIZE = 500  # ブログカード用の中央正方形領域
TITLE = "AIでサムネイル自動生成の実現方法"
KEYWORDS = ["SDXL", "Ollama", "Pillow"]  # LLMが記事から抽出

# --- 背景画像の読み込み(SDXL生成済み) ---
bg = Image.open("generated_bg.png").resize((IMG_WIDTH, IMG_HEIGHT))

# --- 中央に暗めの矩形オーバーレイを配置 ---
overlay = Image.new("RGBA", (IMG_WIDTH, IMG_HEIGHT), (0, 0, 0, 0))
draw_overlay = ImageDraw.Draw(overlay)
x1 = (IMG_WIDTH - SQUARE_SIZE) // 2
y1 = (IMG_HEIGHT - SQUARE_SIZE) // 2
draw_overlay.rectangle([x1, y1, x1 + SQUARE_SIZE, y1 + SQUARE_SIZE], fill=(0, 0, 0, 140))
bg = Image.alpha_composite(bg.convert("RGBA"), overlay)

# --- テキスト描画 ---
draw = ImageDraw.Draw(bg)
font_title = ImageFont.truetype("/usr/share/fonts/NotoSansJP-Bold.ttf", 42)
font_kw = ImageFont.truetype("/usr/share/fonts/NotoSansJP-Regular.ttf", 24)

# タイトルを中央配置
bbox = draw.textbbox((0, 0), TITLE, font=font_title)
tw = bbox[2] - bbox[0]
draw.text(((IMG_WIDTH - tw) // 2, IMG_HEIGHT // 2 - 40), TITLE, font=font_title, fill="white")

# キーワードを下部に配置
kw_text = "  |  ".join(KEYWORDS)
bbox_kw = draw.textbbox((0, 0), kw_text, font=font_kw)
kw_w = bbox_kw[2] - bbox_kw[0]
draw.text(((IMG_WIDTH - kw_w) // 2, IMG_HEIGHT // 2 + 30), kw_text, font=font_kw, fill="#cccccc")

# --- 保存 ---
bg.convert("RGB").save("thumbnail.png", quality=95)

# --- 生成情報をJSONで保存 ---
meta = {
    "title": TITLE,
    "keywords": KEYWORDS,
    "bg_prompt": "digital workspace with AI neural network...",
    "font_title": {"name": "NotoSansJP-Bold", "size": 42},
    "font_keyword": {"name": "NotoSansJP-Regular", "size": 24},
    "overlay_opacity": 140,
}
with open("thumbnail_meta.json", "w", encoding="utf-8") as f:
    json.dump(meta, f, ensure_ascii=False, indent=2)

生成情報の保存

記事は一度公開した後も、いわゆるリライトとして、内容の更新や修正が入ることがあります。 生成したプロンプト、文字を配置する装飾情報などを保存しておくことで、後続のメンテナンスを効率化できます。

作業履歴をJSONでフォーマットして記録しておきます。 JSONであれば、のちのち装飾の内容を変えたりしても柔軟に扱いやすい利点があります。

{
  "title": "AIでサムネイル自動生成の実現方法",
  "keywords": ["SDXL", "Ollama", "Pillow"],
  "background_prompt": "digital workspace with AI neural network visualization, futuristic technology concept, abstract geometric patterns, soft blue and purple gradient",
  "image": {
    "width": 1200,
    "height": 630
  },
  "overlay": {
    "shape": "square",
    "size": 500,
    "opacity": 140
  },
  "fonts": {
    "title": {
      "name": "NotoSansJP-Bold",
      "size": 42
    },
    "keywords": {
      "name": "NotoSansJP-Regular",
      "size": 24
    }
  },
  "generated_at": "2026-03-07"
}

自動化のポイント

今回作成したサムネイルの例です。クォリティはまずまずとして、作業時間は大幅に短縮できました。

まとめ

Canva手動作業の代替として、SDXLとLLMを組み合わせた自動生成ワークフローを構築。高画質画像とレイアウトの最適化により、記事のクォリティと作業効率を両立。生成情報の管理で長期的なメンテナンスを可能にします。

タイトルとURLをコピーしました