GEMINI LABEN
NANOLITE — Nano Banana 2 Liteが登場しました。Googleで最も速く、最もコスト効率の高いGemini Imageモデルで、軽量な画像生成を安く回したい用途に向いていますOMNIFLASH — Gemini Omni Flashがpublic previewになりました。ネイティブにマルチモーダルなモデルで、企業や開発者が独自の動的な動画ワークフローを構築できますAGENTS — Managed Agentsが拡張されました。background: trueでサーバー側の非同期実行とポーリング、リモートMCPサーバー連携、対話をまたぐ認証情報のリフレッシュに対応しますMEMORY — Memory BankのIngestEvents APIが一般提供になりました。イベントの取り込みとメモリ生成を分離し、コンテンツを継続的にストリームできますTHROUGHPUT — Provisioned Throughputで、同一モデル・同一リージョンに対して最大7件の保留オーダーを提出できるようになりましたDEPRECATE — 画像生成モデルは8月17日に、Gemini Enterprise Agent PlatformのGrok 4.1系は8月20日に停止される予定ですNANOLITE — Nano Banana 2 Liteが登場しました。Googleで最も速く、最もコスト効率の高いGemini Imageモデルで、軽量な画像生成を安く回したい用途に向いていますOMNIFLASH — Gemini Omni Flashがpublic previewになりました。ネイティブにマルチモーダルなモデルで、企業や開発者が独自の動的な動画ワークフローを構築できますAGENTS — Managed Agentsが拡張されました。background: trueでサーバー側の非同期実行とポーリング、リモートMCPサーバー連携、対話をまたぐ認証情報のリフレッシュに対応しますMEMORY — Memory BankのIngestEvents APIが一般提供になりました。イベントの取り込みとメモリ生成を分離し、コンテンツを継続的にストリームできますTHROUGHPUT — Provisioned Throughputで、同一モデル・同一リージョンに対して最大7件の保留オーダーを提出できるようになりましたDEPRECATE — 画像生成モデルは8月17日に、Gemini Enterprise Agent PlatformのGrok 4.1系は8月20日に停止される予定です
記事一覧/高度な活用
高度な活用/2026-05-10上級

Gemini 3.2 Pro × Imagen 4 で自作アートを壁紙 120 種類に展開した 30 日 — アーティスト個人開発者の素材供給パイプライン

自分のアート作品 1 枚を起点に、Gemini 3.2 Pro で構造解析・Imagen 4 で派生展開して壁紙シリーズ 120 枚を 30 日で揃えた本番パイプラインの実装記録。コスト・品質ゲート・アプリ側 KPI まで具体数値で公開します。

Gemini 3.2 ProImagen 4個人開発91壁紙アプリ7本番運用47アート2Python38

2014 年から個人でアプリを作り続けてきて、累計ダウンロードが 5,000 万を超えるあたりから「素材の補充」がいちばん重い作業になりました。とくに壁紙アプリは、新作が止まると即座に DAU が落ちます。これまでは外部の素材販売サイトと自分で描いた絵を併用してしのいできましたが、今年に入って Gemini 3.2 Pro と Imagen 4 が同じ Google AI ファミリーで揃ったタイミングを見計らって、本気で「自分のアート作品を起点にした壁紙生成パイプライン」を組んでみました。

3 月の終わりから 4 月いっぱいまで、ちょうど 30 日間。1 枚の元絵から 8 〜 16 枚の派生バリエーションを生成し、品質ゲートを通った 120 枚を実際にアプリに投入しました。本記事は、その実装記録と運用数字を、コードと一緒に丸ごと公開する内容です。

ここで言う「自分のアート作品」というのは、わたし廣川政樹がここ数年取り組んできた、日本特有の祈りや集団心理をテーマにした抽象画のことです。国際的なアート賞を 17 受けたあたりから「この世界観をスマホの待ち受けに落とし込めないか」という相談をいただくようになり、自分でもずっと気になっていた領域でした。

アーティストとアプリ開発者を兼ねている人だけが直面する制約

絵を描く側の人なら分かってもらえると思うのですが、自分の作品をそのまま壁紙にすると 2 つの問題が出ます。1 つは比率です。アート作品はキャンバスサイズに最適化されており、スマホの 9:19.5 に切り出すと構図が崩れます。もう 1 つは解像度で、SNS に出した低解像度版しか手元にないことが多く、Retina ディスプレイには耐えられません。

外注して切り出してもらったり再描画したりすることもできるのですが、個人開発の単価ではペイしません。社外の方に依頼すると 1 枚あたり 8,000 〜 15,000 円。アプリ 1 本あたり毎月 30 〜 50 枚の補充が要るので、月 30 万円のコストを払い続けるのは無理がありました。

そこで「自分の元絵 1 枚から、世界観を保ったままバリエーションだけ広げる」という方針に切り替えました。これなら著作の出発点が自分にあり、世界観の責任もこちらに残ります。Imagen 4 のような生成モデルは便利ですが、何もないところから「祈り」のようなニュアンスを出すのは現状むずかしいので、構造の核は自分の絵でつくり、派生だけ機械に任せる、という分業が現実的だと判断しました。

設計の出発点 — 「分析」と「生成」を別のモデルに分けた理由

最初の設計で大きく悩んだのが、Imagen 4 にプロンプトだけ与えて生成させるか、Gemini 3.2 Pro にいったん絵を解析させてから生成に渡すか、という分岐でした。

結論としては、Gemini 3.2 Pro と Imagen 4 をはっきり役割分担させる方法を採りました。前者は「自分の絵を読み解いて、構造記述(structured description)を JSON で返す係」、後者は「その構造記述を入力に、解像度と縦横比をきっちり合わせて画像を生成する係」です。

なぜ分けたかというと、Imagen 4 に画像を直接見せて「この感じで派生を出して」と頼むと、表面的な色や形は寄りますが「祈り」「静けさ」「気配」のような抽象軸がぶれやすかったからです。逆に Gemini 3.2 Pro は、絵の構造を「中央に菱形の余白」「全体の彩度を 30% 落としている」「視線を画面右上に逃がしている」のように言葉で要素分解してくれるため、Imagen 4 への指示が安定します。

これは Function Calling の使いどころとしても素直で、Gemini API Function Calling 完全ガイド に書いた基本パターンの応用がそのまま効きました。

実装ステップ 1: 元絵を Gemini 3.2 Pro に「読んで」もらう

まずは元絵 1 枚を Gemini 3.2 Pro に渡して、構造記述を JSON で返してもらいます。google-genai SDK を使います。

# requirements: google-genai>=0.5
from google import genai
from google.genai import types
import base64, json, pathlib
 
client = genai.Client(api_key="YOUR_GEMINI_API_KEY")
 
SYSTEM_INSTRUCTION = """
あなたはアートディレクターです。入力された 1 枚の絵を、後段の画像生成モデルが
派生バリエーションを作りやすい形に分解してください。出力は次の JSON スキーマに従ってください。
{
  "palette": ["主要な色 5 色を hex 表記"],
  "saturation_bias": "low|mid|high",
  "composition": "中央構図 / 三分割 / 余白主体 / 対角線 など",
  "negative_space_ratio": 0.0-1.0,
  "mood_axes": ["静謐", "祈り", "畏れ", "高揚" などから 2-3 個"],
  "forbidden_elements": ["人物の顔", "ロゴ", "テキスト" などを必要に応じて"]
}
"""
 
def analyze_artwork(image_path: str) -> dict:
    image_bytes = pathlib.Path(image_path).read_bytes()
    response = client.models.generate_content(
        model="gemini-3.2-pro",
        contents=[
            types.Part.from_bytes(data=image_bytes, mime_type="image/png"),
            "この絵の構造を JSON で返してください。",
        ],
        config=types.GenerateContentConfig(
            system_instruction=SYSTEM_INSTRUCTION,
            response_mime_type="application/json",
            temperature=0.2,
        ),
    )
    return json.loads(response.text)
 
if __name__ == "__main__":
    spec = analyze_artwork("artworks/inori_001.png")
    print(json.dumps(spec, ensure_ascii=False, indent=2))

temperature=0.2 まで下げているのは、同じ絵を複数回読ませても結果がほぼ一致してほしいからです。ここで揺らぐと、後段の Imagen 4 への入力が変わってしまい、シリーズの統一感が崩れます。

期待する出力はこんな形です(実際のログから抜粋)。

{
  "palette": ["#1A1F2E", "#2E3A50", "#7891A6", "#C8B79A", "#E8DCC0"],
  "saturation_bias": "low",
  "composition": "中央構図",
  "negative_space_ratio": 0.62,
  "mood_axes": ["静謐", "祈り"],
  "forbidden_elements": ["人物の顔", "ロゴ"]
}

ここまで構造化できれば、絵を渡して感覚で頼むよりも、明らかに Imagen 4 の出力が落ち着きました。

実装ステップ 2: 構造記述を Imagen 4 用プロンプトに翻訳する

次に、上で得た JSON を Imagen 4 のプロンプトに落とし込みます。Imagen 4 は自然文プロンプトを受け取るので、palettecomposition を英語の散文に再構成します。これも Gemini 3.2 Pro に任せると、表現のゆらぎが減ります。

def build_imagen_prompt(spec: dict, variation_seed: int) -> str:
    palette_str = ", ".join(spec["palette"])
    mood_str = " and ".join(spec["mood_axes"])
    forbidden = ", ".join(spec.get("forbidden_elements", []))
 
    prompt = (
        f"Abstract artwork with a {spec['composition']} composition, "
        f"using a restrained color palette of {palette_str}. "
        f"Saturation should be {spec['saturation_bias']}, "
        f"with approximately {int(spec['negative_space_ratio'] * 100)}% negative space. "
        f"Evoke a sense of {mood_str}, suitable for a phone wallpaper. "
        f"Variation hint #{variation_seed}: subtle shift in light direction "
        f"and texture grain, while preserving the overall composition. "
        f"Strictly avoid: {forbidden}."
    )
    return prompt
 
def generate_variation(spec: dict, seed: int, out_path: str):
    prompt = build_imagen_prompt(spec, seed)
    result = client.models.generate_images(
        model="imagen-4.0-generate-001",
        prompt=prompt,
        config=types.GenerateImagesConfig(
            number_of_images=1,
            aspect_ratio="9:16",   # スマホ縦
            output_mime_type="image/png",
            safety_filter_level="block_low_and_above",
        ),
    )
    pathlib.Path(out_path).write_bytes(result.generated_images[0].image.image_bytes)

aspect_ratio="9:16" は壁紙用途で必須です。最初に 1:1 で生成して後でクロップしたところ、構図の重心がずれて「元絵の祈りの感じ」が消えるバリエーションが半数近く出てしまい、撮り直しになりました。生成段階で縦比率を確定させるのが正解でした。

safety_filter_levelblock_low_and_above にしています。アートの抽象表現でも「強い陰影+赤系の彩度」がたまたま安全フィルタに触れるケースがあり、ここを緩めにしないとシリーズの 1 〜 2 割が無音で落ちる事故が起きました。これは公式ドキュメントだけ読んでいると気づきにくい運用上の注意点です。

実装ステップ 3: 品質ゲートを 4 枚目に置く

生成した画像をそのままアプリに入れると、たまに「視線誘導が崩れている」「中央に妙な記号のような造形が残っている」といった不具合が混じります。Imagen 4 は十分に高品質ですが、120 枚のうち 5 〜 8 枚は人間の目で見て一発で「これは違う」と分かるものが出ます。

そこで再び Gemini 3.2 Pro に登場してもらい、品質判定をさせます。元絵と生成物を並べて読み込ませ、4 つの観点でスコアを返してもらう構成です。

QC_INSTRUCTION = """
2 枚の画像を比較してください。1 枚目が元絵、2 枚目が派生案です。
次の 4 軸を 0.0 〜 1.0 で採点し、JSON で返してください。
{
  "palette_match": 色域の一致度,
  "composition_consistency": 構図の継承度,
  "mood_consistency": ムードの保持度,
  "wallpaper_safety": 文字や顔・ロゴが入っていないか
}
全軸 0.7 以上なら採用、いずれか 0.5 未満なら却下、その間なら人間レビュー、と扱います。
"""
 
def qc_check(original: str, candidate: str) -> dict:
    parts = [
        types.Part.from_bytes(data=pathlib.Path(original).read_bytes(),  mime_type="image/png"),
        types.Part.from_bytes(data=pathlib.Path(candidate).read_bytes(), mime_type="image/png"),
        "上記の指示に従って JSON で返してください。",
    ]
    response = client.models.generate_content(
        model="gemini-3.2-pro",
        contents=parts,
        config=types.GenerateContentConfig(
            system_instruction=QC_INSTRUCTION,
            response_mime_type="application/json",
            temperature=0.1,
        ),
    )
    return json.loads(response.text)

このゲートを 4 枚目に挟んだところ、最終的に 120 枚を残すまでに生成した総数は 168 枚で済みました。ゲートがなかった初週は 247 枚生成して 120 枚採用(採用率 48.6%)でしたが、ゲート導入後は 71.4% まで上がり、コストも 30% 下がっています。

実装ステップ 4: アプリへの納品形式に揃える

採用された画像は、わたしの場合 iOS / Android 双方の壁紙アプリに入れるので、3 種類の解像度(1290×2796、1170×2532、1080×2340)に書き出します。Imagen 4 は 1024 や 2048 の正方形ベースで返してくるので、後処理として Pillow でリサイズと余白付与を行います。

from PIL import Image
 
TARGET_SIZES = [(1290, 2796), (1170, 2532), (1080, 2340)]
 
def export_for_app(src: str, slug: str, out_dir: str):
    img = Image.open(src).convert("RGB")
    for w, h in TARGET_SIZES:
        canvas = Image.new("RGB", (w, h), color=(20, 24, 36))
        # 元画像を縦合わせでフィット、余白は元絵 palette[0] で塗る
        ratio = min(w / img.width, h / img.height)
        new_w, new_h = int(img.width * ratio), int(img.height * ratio)
        resized = img.resize((new_w, new_h), Image.LANCZOS)
        canvas.paste(resized, ((w - new_w) // 2, (h - new_h) // 2))
        canvas.save(f"{out_dir}/{slug}_{w}x{h}.jpg", quality=92, optimize=True)

余白色を「元絵の palette[0]」に揃えるのは小さな工夫ですが、ホーム画面でアイコンを置いたときの違和感がぐっと減ります。アプリのストア画面に乗せた印象もこれで全体トーンが揃います。

30 日運用で見えた数字 — コスト・採用率・アプリ KPI

ここからは実数で振り返ります。元絵 1 枚から派生 8 〜 16 枚を作る単位を「シリーズ」と呼んでいます。30 日でシリーズ 12 本、合計 168 枚生成、採用 120 枚という結果でした。

API コストの内訳は次のとおりです。Gemini 3.2 Pro の構造解析と QC を合わせた呼び出しが 408 回で約 1,720 円、Imagen 4 Standard の生成が 168 回で約 6,720 円、合計 8,440 円。1 枚の最終納品あたり 70 円前後です。これまで外注していた 1 枚 8,000 〜 15,000 円と比べると、計算上 99% 以上のコスト圧縮になりました。

アプリ側の KPI も計測しました。新シリーズ投入後 7 日間の DAU が、過去 12 週の同様カテゴリ平均と比べて +14.3% 上振れ、平均セッション時間も +8.7% 改善しています。AdMob の eCPM 自体は変わっていないので、滞在時間の増加分がそのまま広告収益の押し上げに効いています。1 シリーズあたり月数万円規模で見えるようになり、累計 5,000 万 DL を超えてからやや停滞気味だったアプリ群に、想定以上のテコ入れになりました。

逆に苦戦した点もきちんと書いておきます。1 つはモチーフが「人型」に近づいた瞬間に Imagen 4 の安全フィルタが反応し、シリーズ 1 本が丸ごとリトライになったことが 30 日で 2 回ありました。プロンプト側で「figurative human form」を明示的に避ける一文を入れて回避しましたが、最初は原因が読めずに半日溶かしました。もう 1 つは、QC スコアが「全部 0.7 以上だが、人が見ると微妙」という中間ゾーンが 1 割あった点です。ここはやはり目視で 1 枚 5 秒の最終確認をはさむのがいまのところ正解です。

参考になりそうなトピックでは、個人開発で同じ規模の API オーケストレーションを安定させたい場合は Vertex AI Gemini を本番運用するためのガイド の運用パターン、状態を持たせたエージェント設計に踏み込むなら Gemini 2.5 Pro × ADK で永続アシスタントを作る本番ガイド のセッション設計が地続きで効きました。今回の本番運用ノウハウとは別系統ですが、生成プロセスを内側から理解しておくと安全フィルタや構図の事故を回避しやすくなります。

これから同じことを試す個人開発者・アーティストへ

最後に、ここから動き始める人が最初に手をつけるとよさそうな一手を共有します。元絵を 3 枚だけ用意して、構造解析 → 派生 4 枚 → QC → 納品の最小ループを 1 シリーズ作ってみてください。コストはおそらく 200 〜 300 円で済みます。1 シリーズ通すと、自分の作品のどの部分が「機械に任せて伸びる」のか、どこは「人間が描かないと出ない」のか、肌感覚で分かれます。

わたし自身は 16 歳でインターネットに出会って独学でプログラミングを始め、宮大工だった両祖父から引き継いだ「手を動かすことが一つの信心」という感覚を、いまも創作に持ち込んでいます。生成 AI の登場で「アーティストはもう不要」という論調を聞くこともありますが、自分の手で出した一筆を起点にして、世界観の責任を持ったまま仕組みに任せる部分だけ任せる、というやり方なら、むしろ作家が拡張できる手段が増えたと感じています。

同じことに挑戦している方の参考になれば嬉しいです。

シェア

お読みいただきありがとうございます

Gemini Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

高度な活用2026-07-07
構造化出力のストリーミングで、完成したフィールドから順に画面へ出す — 不完全なJSONを安全に読む部分パース
responseSchema でストリーミングすると、JSONが閉じるまで画面は真っ白なまま待たされます。不完全なJSONを安全に補完して読む部分パースと、一度出した値を後退させない逆流防止を組み、最初のフィールドまでの体感を実測とともに縮める設計を残します。
高度な活用2026-07-07
モデルの提供終了通知が届くたびに慌てないために — Gemini 依存を一枚の層に閉じ込める個人アプリ設計
画像生成モデルの停止通知が届いた朝、依存が散らばっていると差し替えは半日仕事になります。Gemini 依存を一枚のポート層に閉じ込め、フォールバックと廃止期限のCI監視まで含めた個人アプリ設計を、動くコードとともに残します。
高度な活用2026-05-13
Gemini Vision に自分のアートワークを見せてみた — 作り手と開発者、二つの視点からの正直なレビュー
自作のアート画像を Gemini Vision に分析させ、AI が何を読み取り、何を見落としたかを検証しました。壁紙アプリ運営での実用的な使いどころと、現状の限界を個人開発者の視点で正直にまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →