1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AI で作った UI 画像を OGP / SNS preview に出す前に確認すること

1
Posted at

AI で hero 画像や UI モックっぽい画像を作るのは、もうかなり速い。

でも個人開発で実際に詰まるのは、画像を作るところより、その画像が OGP や SNS preview でどう切られるかを見るところだったりする。ローカルで見た時はいい感じなのに、X のカード、Facebook のリンクプレビュー、Slack、Discord で見ると文字が端で切れる。サムネイルになると細部が潰れる。キャッシュが残っていて、直したはずの画像がいつまでも出てこない。

これ、AI 画像生成の問題というより「公開 asset として扱っていない」問題だと思っている。

OGP は実装ではなく公開 asset

Next.js App Router だと、app/opengraph-image.tsx や route ごとの opengraph-image.tsx で OGP 画像を生成できる。ImageResponse を使えば JSX から画像を作れるので、タイトル、日付、ブランド要素を動的に入れるのも難しくない。

例えば最小構成ならこういう形になる。

// app/opengraph-image.tsx
import { ImageResponse } from "next/og";

export const size = {
  width: 1200,
  height: 630,
};

export const contentType = "image/png";

export default function Image() {
  return new ImageResponse(
    (
      <div
        style={{
          width: "100%",
          height: "100%",
          display: "flex",
          flexDirection: "column",
          justifyContent: "center",
          padding: "72px",
          background: "#111827",
          color: "white",
          fontSize: 56,
          fontWeight: 700,
        }}
      >
        AI で作った画像を公開前に見る
      </div>
    ),
    size,
  );
}

実装としては気持ちいい。ページと同じリポジトリで管理できるし、画像を手で書き出して置くより変更にも強い。

ただ、ここで止まると危ない。

1200 x 630 の画像が生成できたことと、公開先でちゃんと見えることは別物だからだ。OGP は「生成できる画像」ではなく「外部サービスに食われる公開 asset」として見る方が事故が減る。

まず見るべき壊れ方

自分がチェックリストに入れているのは、このへん。

文字が端に寄りすぎていないか

OGP は 1200 x 630、だいたい 1.91:1 の横長で作ることが多い。でも実際の表示面はサービスごとに違う。角丸になったり、少し縮んだり、上下左右に余白が乗ったりする。

特に AI で作った背景画像の上に文字を載せる場合、背景の主題に合わせて文字位置を詰めたくなる。見た目は締まる。でもプレビューでは端の余白が少ない画像ほど弱い。

自分なら、重要な文字とロゴはかなり内側に置く。ざっくり中央 70% くらいに主題を収める感覚で、端は捨てる。デザイナーっぽい詰めより、事故らない余白を優先する。

横長だけで完結していないか

OGP 用の横長画像だけ見ていると、SNS 投稿用の正方形や縦長に流用した時に壊れる。

最低限、この 4 パターンは見たい。

  • 1200 x 630: OGP / link preview 用の横長
  • 1080 x 1080: 正方形の投稿や一覧サムネイル
  • 1080 x 1350: 4:5 の縦長 feed
  • 1080 x 1920: Story / Reels 系の縦長

同じ一枚から全部を作る必要はない。むしろ、main visual と SNS 用 crop は別 asset として扱った方がいい。横長で気持ちいい構図は、縦長ではだいたい苦しい。

AI 画像の細部が縮小でノイズになっていないか

AI 生成画像は、原寸で見るとリッチに見える。でも小さくなると、細かい UI、疑似テキスト、ぼかしたアイコン、意味ありげな線が一気にノイズになることがある。

OGP の一覧表示はそこまで大きくない。スマホのフィードならなおさら小さい。

なので、生成画像をそのまま信じずに、一度かなり小さい表示で見る。ブラウザで 50% 表示にするだけでもいい。小さくした時に「何の画像か」が残らないなら、背景を整理するか、文字を強くするか、別画像にした方がいい。

dark / light の両方で読めるか

外部サービスのプレビュー面は、自分のサイトの背景色とは違う。ダークテーマの UI で見る人もいれば、ライトテーマで見る人もいる。

画像の外側に白い余白が出るサービスもある。黒背景に白文字だけで作った画像が、ライトテーマの中では強すぎることもある。逆に淡い画像は、ダークテーマのカード内で眠くなる。

画像単体で見るのではなく、白い背景と暗い背景の上に置いて見る。これだけで「公開したら思ったより読めない」はかなり減る。

自分用の公開前 checklist

実装後は、だいたいこの順で見ている。

  1. opengraph-image.tsx で横長 OGP を生成する
  2. ローカルで 1200 x 630 の出力を開く
  3. 重要な文字とロゴが中央安全地帯に入っているか見る
  4. 正方形、4:5、9:16 の見え方を別 asset として確認する
  5. 小さい表示で、AI 画像の細部がノイズになっていないか見る
  6. 実 URL で OGP preview を見る
  7. キャッシュを疑って、必要なら query 付き URL や各サービスの debug tool で再取得する

ここで大事なのは、local preview と実 URL preview を分けること。

ローカルで画像がきれいに出るのは第一段階。外部サービスが実 URL を読めるか、正しい metadata を拾っているか、古い画像をキャッシュしていないかは別の確認になる。

SNS 用サイズは生成とは別工程にする

AI で作った launch 用画像を、そのまま OGP、X 投稿、Instagram、Facebook、Qiita 記事内画像に全部使い回すと、どこかで無理が出る。

自分は最近、生成画像を「素材」として扱うようにしている。完成画像ではない。

例えばこういう流れ。

AI image generation
  -> main visual として使えるか確認
  -> OGP 用に横長で再配置
  -> SNS 投稿用に正方形 / 縦長を別途確認
  -> 実 URL preview でキャッシュ込みの見え方を確認

この途中で、画像を browser-local に social-ready size へ整える補助として Resize Image For みたいなツールを挟むと楽になる。元画像をサーバーにアップロードせず、Instagram や Facebook 系の比率を見ながら fit / fill / stretch の違いを確認できるので、「AI で作った一枚をどの面に出すか」を決める作業に向いている。

ポイントは、リサイズツールに丸投げすることではない。先に「どの面で何を残すか」を決める。その上で、サイズ合わせと crop 確認を機械的な工程に落とす。

Next.js でやるなら preview route を作るのもあり

opengraph-image.tsx は公開用の画像生成として便利だけど、確認用 UI には少し向かない。

自分なら、開発中だけでも preview 用の route を作る。

// app/og-preview/page.tsx
const surfaces = [
  { name: "OGP", width: 1200, height: 630 },
  { name: "Square", width: 1080, height: 1080 },
  { name: "Portrait", width: 1080, height: 1350 },
  { name: "Story", width: 1080, height: 1920 },
];

export default function OgPreviewPage() {
  return (
    <main style={{ padding: 24 }}>
      {surfaces.map((surface) => (
        <section key={surface.name} style={{ marginBottom: 32 }}>
          <h2>{surface.name}</h2>
          <div
            style={{
              width: 360,
              aspectRatio: `${surface.width} / ${surface.height}`,
              border: "1px solid #ddd",
              overflow: "hidden",
            }}
          >
            <img
              src="/generated-launch-image.png"
              alt=""
              style={{
                width: "100%",
                height: "100%",
                objectFit: "cover",
              }}
            />
          </div>
        </section>
      ))}
    </main>
  );
}

これは雑な例だけど、見るべきことははっきりしている。

object-fit: cover で切った時に主題が残るか。contain にした時に余白がだらしなくならないか。文字を画像に焼き込むべきか、HTML 側で載せるべきか。

この確認を後回しにすると、公開直前に「画像だけ作り直し」になる。地味に痛い。

cache は最後に必ず疑う

OGP まわりで一番つまらない時間の溶け方は、直した画像が反映されない問題だと思う。

画像生成コードは直っている。実 URL を直接開くと新しい画像が出る。でも SNS preview は古いまま。だいたいキャッシュ。

対策としては、少なくともこの 3 つを分けて見る。

  • 画像 URL を直接開いた結果
  • ページ HTML の metadata が指している画像 URL
  • 外部サービスの preview が実際に拾った結果

/opengraph-image のような URL が同じままだと、サービス側のキャッシュに引っ張られることがある。検証時は query を付けた URL を一時的に使う、画像 URL に version を入れる、debug tool で再取得する、などを運用として決めておくと楽になる。

ここは技術的に難しいというより、確認順を決めていないと毎回迷う。

まとめ

AI 画像生成は入口としてはかなり便利になった。個人開発でも、launch 用の visual を作る速度は明らかに上がっている。

でも公開 asset の品質は、生成できた瞬間には決まらない。

OGP で読めるか。正方形や縦長でも主題が残るか。小さくした時にノイズにならないか。外部サービスのキャッシュ込みで、実際の preview が正しく出るか。

そこまで見て、ようやく「公開できる画像」になる。

自分の中では、AI で画像を作る作業と、SNS で壊れない asset にする作業は別工程。ここを分けておくと、公開直前の手戻りがかなり減る。

source notes

  • Next.js opengraph-image file convention
  • Next.js ImageResponse
  • Resize Image For local project notes and public page metadata
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?