ブラウザだけで動くAIサムネ生成アプリを作った話

公開: 2026-05-26
開発日記AIWebGPUCloudflareサムネイル

ブラウザAIが生成したネオンコードのビジュアル

note記事を書くたびにサムネイルを作るのが面倒でした。Canvaで文字を打って、サイズを調整して、ダウンロードして——毎回同じ作業の繰り返し。「どうせなら自動化したい」と思い、AIでサムネを生成するアプリを作りました。


何を作ったか

テキストを入力するとAIが画像を生成し、そこにタイトルと説明文を合成してPNGでダウンロードできるツールです。シーン・スタイル・ムード・構図のプリセットを組み合わせて、英語プロンプトを自動で組み立てる仕組みにしました。

thumbnail-appの処理フロー

特徴的なのはすべてブラウザ内で完結する点です。画像データは外部サーバーに送らず、AIの推論もブラウザのWebGPU上で動かします。APIキーも不要、課金もなし。


なぜAPIを使わなかったのか

最初はOpenAIのDALL-Eを使う案も考えました。実装は簡単ですが、ユーザーが使うたびに従量課金が発生します。個人開発のツールで不特定多数が使った場合、コストがコントロールできなくなるリスクがあります。

「ユーザーのデバイスで推論させれば課金ゼロ」という発想に至り、WebGPUを試してみることにしました。Transformers.jsを使うとJavaScriptだけでStable Diffusionを動かせることを知ったのも、この時期です。


WebGPUとCPUフォールバック

WebGPUは比較的新しいブラウザAPIで、まだ非対応の環境もあります。特にiOSのSafariや古いChromiumでは使えません。

対応策として、WebGPUが使えない場合は自動でCPU推論にフォールバックする実装を入れました。CPUだと生成に数十秒かかりますが、動かないよりはいい。

const isWebGPUAvailable = async () => {
  if (!navigator.gpu) return false;
  try {
    const adapter = await navigator.gpu.requestAdapter();
    return !!adapter;
  } catch {
    return false;
  }
};

この判定をページ読み込み時に実行して、UIに「ブラウザAI対応」バッジを出すようにしました。ユーザーが自分の環境を把握できるようにしたかったからです。


プリセットシステムの設計

サムネの仕上がりはプロンプトで9割決まります。しかし毎回英語でプロンプトを書くのは手間がかかるし、そもそも何を書けばいいか分からない人も多い。

そこでシーン・スタイル・ムード・構図の4軸でプリセットを用意し、選ぶだけで英語プロンプトが組み上がる仕組みにしました。

「アニメ風 × 都市夜景 × 未来的」のような組み合わせで、それっぽい画像が出てくるのが面白いです。


Canvas合成で詰まったこと

AI生成した画像の上にタイトルと説明文を描画する部分で、文字の折り返し処理に手間取りました。Canvasの fillText は自動折り返しをしてくれないので、自前で実装する必要があります。

文字幅を measureText で計りながら1単語ずつ追加していく実装を書いたのですが、日本語の場合は単語の区切りが英語と違います。最終的に文字数ベースの単純な折り返しで妥協しました。完全な解決ではないけれど、実用上は問題ありません。


Cloudflare Pagesでのホスティング

静的ファイル(HTML/CSS/JS)だけで構成されているので、Cloudflare Pagesにそのままデプロイできます。フレームワークなし、ビルドステップなし、public/ ディレクトリをそのまま公開する形です。

wrangler.toml に1行設定するだけで済みました。

pages_build_output_dir = "public"

サーバーレスで世界中のエッジから配信されるので、レスポンスも速いです。AIモデルのダウンロード(初回起動時)だけが少し重いですが、2回目以降はブラウザにキャッシュされます。


まとめ

thumbnail.codese.net で公開中です。ブラウザのWebGPU対応状況によって速度は変わりますが、Chrome最新版なら快適に動きます。note記事を書く前にぜひ試してみてください。