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日に停止される予定です
記事一覧/API / SDK
API / SDK/2026-05-03中級

Gemini Vision APIで壁紙アプリの画像を自動カテゴリ分類する — 3000枚を30カテゴリに処理した実践記録

壁紙アプリの画像3000枚を手動で分類するのは現実的ではありません。Gemini Vision APIを使った自動カテゴリ分類パイプラインの設計と実装、コスト分析まで、実際に動かして見えてきたことをすべて書きます。

Gemini API191Vision API画像分類4壁紙アプリ7バッチ処理6個人開発91

壁紙アプリを個人で開発・運営していると、ある時点で必ず直面する問題があります。

「画像が増えすぎて、カテゴリ分類が追いつかない」

わたしが運営する壁紙アプリには、現在3000枚以上の壁紙画像が登録されています。最初は手動で分類していましたが、月に数百枚ペースで追加していると、分類作業だけで週に数時間を奪われるようになりました。

そこで試したのがGemini Vision APIを使った自動分類です。結論から言うと、精度90%超・コスト1000枚あたり数十円という結果が出ました。ここでは設計から実装、実際に運用してわかったことまで書きます。

課題の整理: なぜ手動分類は限界なのか

壁紙アプリのカテゴリ分類は、一見単純な作業に見えます。「これは自然風景」「これはミニマリスト」「これはダークテーマ」と判断するだけです。

しかし実際にやってみると、3つの問題が出てきます。

問題1: 判断のブレ
同じ画像でも、疲れているときと集中しているときで分類が変わることがあります。ユーザーが「このカテゴリ変じゃない?」とレビューで指摘してくれることが何度かありました。

問題2: スケーラビリティ
100枚なら手動でもできます。1000枚になると1日がかりです。3000枚を超えると、追加のたびに分類が遅れてリリースが詰まります。

問題3: 多言語対応
アプリが多言語対応している場合、カテゴリ名の翻訳作業も伴います。「Natural Scenery」「Natürliche Landschaft」…これも全部手動でやっていました。

Gemini Vision APIを選んだ理由

画像分類のAPIは他にもあります。Google Cloud Vision APIやAWSのRekognitionも候補でした。

Gemini Vision APIを選んだ理由は3つです。

理由1: カスタムカテゴリに対応できる
既存の分類APIは「山」「空」「人物」のような汎用カテゴリを返します。でも壁紙アプリには独自のカテゴリがあります。「ローファイ・チルアウト」「グラデーション」「タイポグラフィ」など。Geminiは自然言語でカテゴリを定義して渡せるため、アプリ独自の分類体系に完全対応できます。

理由2: 説明文の同時生成
カテゴリ分類と同時に、「この壁紙の雰囲気の説明文」を生成させることができます。App Store掲載文や多言語タグの自動生成にも使えます。

理由3: コストの予測しやすさ
Gemini Flash(低コストモデル)であれば、1000枚の画像処理が数十円程度で収まります。月次コストの見通しが立てやすい点が個人開発者に向いています。

実装: 分類パイプラインの設計

全体のフローはシンプルです。

画像ファイル一覧取得 → Gemini APIに画像+カテゴリリストを送信
→ レスポンス解析 → DBに分類結果を保存 → 信頼度が低い場合は手動確認キューへ
import google.generativeai as genai
import json
from pathlib import Path
 
genai.configure(api_key="YOUR_GEMINI_API_KEY")
model = genai.GenerativeModel("gemini-2.0-flash")
 
# アプリ独自の30カテゴリを定義
CATEGORIES = [
    "自然風景", "ミニマリスト", "ダークテーマ", "グラデーション",
    "抽象アート", "都市景観", "サンセット", "オーシャン",
    "フォレスト", "スペース・宇宙", "フラワー・植物", "アニマル",
    "テクスチャ", "パターン", "タイポグラフィ", "建築",
    "食べ物", "スポーツ", "テクノロジー", "ゲーム",
    "アニメ・イラスト", "水彩・アート", "モノクロ", "ヴィンテージ",
    "ネオン・サイバーパンク", "和風・日本", "北欧スタイル", "ローファイ",
    "クリスマス・季節", "その他"
]
 
def classify_wallpaper(image_path: str) -> dict:
    """壁紙画像を分類して結果を返す"""
    
    image_file = genai.upload_file(image_path)
    
    prompt = f"""以下の壁紙画像を分析し、最も適切なカテゴリを選んでください。
 
カテゴリ一覧:
{json.dumps(CATEGORIES, ensure_ascii=False)}
 
以下のJSON形式で回答してください:
{{
  "primary_category": "メインカテゴリ名",
  "secondary_category": "サブカテゴリ名(オプション)",
  "confidence": 0.0〜1.0の数値,
  "description_ja": "この壁紙の雰囲気を30文字以内で",
  "description_en": "30-char atmosphere description in English",
  "tags": ["タグ1", "タグ2", "タグ3"]
}}
 
JSONのみ返してください。"""
 
    response = model.generate_content([image_file, prompt])
    
    try:
        result = json.loads(response.text.strip())
        return result
    except json.JSONDecodeError:
        # JSON解析失敗の場合は手動確認キューへ
        return {"primary_category": "その他", "confidence": 0.0, "error": response.text}

バッチ処理: 3000枚を効率よく処理する

1枚ずつ処理すると、Gemini APIのレート制限にぶつかります。適切な間隔を設けながらバッチ処理します。

import time
import asyncio
from pathlib import Path
 
async def classify_batch(image_dir: str, output_file: str):
    """ディレクトリ内の全画像を分類してJSONに保存"""
    
    images = list(Path(image_dir).glob("*.jpg")) + list(Path(image_dir).glob("*.png"))
    results = []
    manual_review_queue = []
    
    print(f"処理対象: {len(images)}枚")
    
    for i, img_path in enumerate(images):
        result = classify_wallpaper(str(img_path))
        result["filename"] = img_path.name
        results.append(result)
        
        # 信頼度0.7未満は手動確認へ
        if result.get("confidence", 0) < 0.7:
            manual_review_queue.append(img_path.name)
        
        # 進捗表示
        if (i + 1) % 50 == 0:
            print(f"処理済み: {i+1}/{len(images)} ({len(manual_review_queue)}件が手動確認待ち)")
        
        # レート制限対策: 0.5秒待機
        time.sleep(0.5)
    
    # 結果を保存
    with open(output_file, "w", encoding="utf-8") as f:
        json.dump({
            "total": len(images),
            "manual_review_count": len(manual_review_queue),
            "manual_review_queue": manual_review_queue,
            "results": results
        }, f, ensure_ascii=False, indent=2)
    
    print(f"完了。手動確認が必要: {len(manual_review_queue)}枚")

実際に動かして気づいたこと

実際に3000枚を処理してみた結果を正直に書きます。

精度について
全体の約93%が「信頼度0.7以上」の自動分類になりました。残り7%(約210枚)が手動確認キューに入りましたが、そのほとんどは「自然風景+ミニマリスト」のように複数カテゴリにまたがる画像でした。

コストについて
Gemini 2.0 Flashを使い、3000枚の処理費用は合計で約450円(画像入力トークン込み)でした。手動で同じ作業をした場合の時間コストと比べると、非常に割安です。

失敗パターン

  • 真っ黒・真っ白に近い画像:「モノクロ」か「ミニマリスト」か迷う
  • 複合的なアート作品:分類が安定しない
  • 解像度が低すぎる画像:詳細が読み取れず精度が落ちる

これらはプロンプトの改良(「迷った場合はその他を選んでください」等の追記)で精度が向上しました。

今後の改善: 分類結果をフィードバックとして活用する

現在、ユーザーのアプリ内行動データ(よく見られる壁紙・お気に入り登録数)をGeminiの分類精度向上に活かす実験を進めています。

「ユーザーが気に入る画像の特徴」をGeminiに学習させると、カテゴリ分類の精度がさらに上がるはずです。これはまだ実験段階ですが、個人開発者がデータを活かしてAIを育てていく良い例になると思っています。

手動作業をAIに任せて浮いた時間は、新しいコンテンツの制作や機能改善に使えます。小さな自動化の積み重ねが、個人開発の持続可能性を高めます。

シェア

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

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

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

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

関連記事

API / SDK2026-07-11
Gemini のコンテキストキャッシュが途中で失効する — 一時停止するパイプラインで TTL 切れを検知して張り直す
夜間バッチや再試行で処理が一時停止すると、Gemini の明示的コンテキストキャッシュは静かに TTL 切れを起こし、以降の呼び出しが全トークン課金へ戻ります。残り有効期限を握って張り直すか素通しするかを費用で決める、小さなリース設計をまとめました。
API / SDK2026-05-19
Gemini Files API と Cloudflare R2 を組み合わせた画像処理パイプライン設計 — 壁紙アプリ運営の実装メモ
Gemini Files API と Cloudflare R2 を組み合わせ、壁紙アプリの画像処理パイプラインを再設計した30日の記録です。48時間制限・冪等性・コスト監視の落とし穴と対処を、実装コードと数値で整理しました。
API / SDK2026-07-19
静止画か短い動画か — Nano Banana 2 Lite と Omni Flash のコスト桁差で機能の置き所を決める
壁紙アプリの目玉アセットを静止画にするか短い動画にするかで手が止まったとき、決め手になったのは好みではなくコストの桁でした。Nano Banana 2 Lite と Omni Flash の単価を同じ土俵に並べ、動く意思決定関数まで落とし込みます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →