Google ColabでGPT Image:猫耳・犬耳キャラクター生成クックブック

チュートリアル

このGoogle Colabクックブックでは、GPT Imageを使用して猫耳女性や犬耳男性などのアニメ風キャラクターを生成・編集する方法を学びます。ブラウザ上で直接実行でき、高品質なキャラクターアートを作成できます。

前回の記事

Google ColabでGPT Image Input fidelityを使った画像の生成と編集
このGoogle Colabクックブックでは、画像生成機能を持つ新しい大規模言語モデルであるGPT Imageの使い方を学びます。このノートブックはGoogle Colab環境で動作し、ブラウザ上で直接実行できます。このモデルは世界に関する...

セットアップ

Google Colab環境で必要なライブラリをインストールし、GPT Imageを使用する準備をします。

%pip install pillow openai -U
import base64
import os
from openai import OpenAI
from PIL import Image
from io import BytesIO
from IPython.display import Image as IPImage, display
import json
# Google Colab環境でAPIキーを安全に設定
from google.colab import userdata
os.environ["OPENAI_API_KEY"]= userdata.get('OPENAI_API_KEY')
client = OpenAI()
# APIキーがグローバルに設定されていない場合は設定
#client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY", "<環境変数として設定されていない場合のOpenAI APIキー>"))
# 画像保存用フォルダの作成(Google Colab環境内)
folder_path = "character_imgs"
os.makedirs(folder_path, exist_ok=True)

基本的なキャラクター生成

猫耳女性キャラクターの生成

まずは基本的な猫耳女性キャラクターを生成してみましょう。

catgirl_prompt = """
アニメスタイルの美しい猫耳女性キャラクター。以下の特徴を持つ:
- 大きくて表情豊かな青い瞳
- ふわふわした茶色の猫の耳(頭の上に2つ)
- 肩まで届く波打つ茶色の髪
- 可愛らしい猫の尻尾
- 学校の制服風の衣装(紺のブレザーと白いシャツ、赤いリボン)
- 穏やかで優しい表情
- 明るい背景
- 高品質なアニメアート、詳細なイラストレーション
"""

catgirl_path = "character_imgs/catgirl_basic.jpg"
# 猫耳女性を生成
result_catgirl = client.images.generate(
    model="gpt-image-1",
    prompt=catgirl_prompt,
    size="1024x1536",  # 縦長のポートレート
    quality="high"
)

# 画像を保存(オリジナルサイズとリサイズ版の両方)
image_base64 = result_catgirl.data[0].b64_json
image_bytes = base64.b64decode(image_base64)

# オリジナルサイズで保存
catgirl_original_path = "character_imgs/catgirl_basic_original.jpg"
image_original = Image.open(BytesIO(image_bytes))
image_original.save(catgirl_original_path, format="JPEG", quality=95, optimize=True)

# リサイズ版を保存
image = Image.open(BytesIO(image_bytes))
image = image.resize((300, 450), Image.LANCZOS)
image.save(catgirl_path, format="JPEG", quality=85, optimize=True)

print("オリジナルサイズ:")
display(IPImage(catgirl_original_path))
print("リサイズ版:")
display(IPImage(catgirl_path))

犬耳男性キャラクターの生成

次に、対照的な犬耳男性キャラクターを作成します。

dogboy_prompt = """
アニメスタイルのかっこいい犬耳男性キャラクター。以下の特徴を持つ:
- 鋭い緑の瞳
- 立ち上がった茶色の犬の耳(頭の上に2つ)
- 短めの黒髪で少し乱れたスタイル
- ふわふわした犬の尻尾
- カジュアルな服装(黒のパーカーとジーンズ)
- クールで自信に満ちた表情
- 都市の背景
- 高品質なアニメアート、詳細なイラストレーション
"""

dogboy_path = "character_imgs/dogboy_basic.jpg"
# 犬耳男性を生成
result_dogboy = client.images.generate(
    model="gpt-image-1",
    prompt=dogboy_prompt,
    size="1024x1536",
    quality="high"
)

# 画像を保存(オリジナルサイズとリサイズ版の両方)
image_base64 = result_dogboy.data[0].b64_json
image_bytes = base64.b64decode(image_base64)

# オリジナルサイズで保存
dogboy_original_path = "character_imgs/dogboy_basic_original.jpg"
image_original = Image.open(BytesIO(image_bytes))
image_original.save(dogboy_original_path, format="JPEG", quality=95, optimize=True)

# リサイズ版を保存
image = Image.open(BytesIO(image_bytes))
image = image.resize((300, 450), Image.LANCZOS)
image.save(dogboy_path, format="JPEG", quality=85, optimize=True)

print("オリジナルサイズ:")
display(IPImage(dogboy_original_path))
print("リサイズ版:")
display(IPImage(dogboy_path))

カスタマイズオプションの探索

透明背景でのキャラクター生成

キャラクターステッカーやアバター用に透明背景のキャラクターを作成してみましょう。

foxgirl_transparent_prompt = """
アニメスタイルの狐耳女性キャラクター、透明な背景:
- オレンジ色の狐の耳と尻尾(白い先端付き)
- 金色の瞳
- オレンジがかった赤毛のロングヘア
- 巫女風の赤と白の衣装
- 神秘的で優雅な表情
- 透明な背景
- 高品質なアニメアート
"""

foxgirl_transparent_path = "character_imgs/foxgirl_transparent.png"
# 透明背景の狐耳女性を生成
result_foxgirl = client.images.generate(
    model="gpt-image-1",
    prompt=foxgirl_transparent_prompt,
    size="1024x1024",
    quality="high",
    output_format="png",
    background="transparent"
)

# 画像を保存(オリジナルサイズとリサイズ版の両方)
image_base64 = result_foxgirl.data[0].b64_json
image_bytes = base64.b64decode(image_base64)

# オリジナルサイズで保存
foxgirl_original_path = "character_imgs/foxgirl_transparent_original.png"
image_original = Image.open(BytesIO(image_bytes))
image_original.save(foxgirl_original_path, format="PNG")

# リサイズ版を保存
image = Image.open(BytesIO(image_bytes))
image = image.resize((300, 300), Image.LANCZOS)
image.save(foxgirl_transparent_path, format="PNG")

print("オリジナルサイズ:")
display(IPImage(foxgirl_original_path))
print("リサイズ版:")
display(IPImage(foxgirl_transparent_path))

品質設定の比較

同じキャラクターを異なる品質設定で生成し、違いを比較してみましょう。

wolf_prompt = """
アニメスタイルの狼耳女性戦士:
- 銀色の狼の耳と尻尾
- 鋭い紫の瞳
- 長い銀髪
- 黒い戦闘服とアーマー
- 凛々しく戦闘的な表情
- 月夜の森の背景
"""

qualities = ["low", "medium", "high"]
wolf_paths = []
wolf_original_paths = []

for i, quality in enumerate(qualities):
    path = f"character_imgs/wolf_girl_{quality}.jpg"
    original_path = f"character_imgs/wolf_girl_{quality}_original.jpg"
    wolf_paths.append(path)
    wolf_original_paths.append(original_path)

    result = client.images.generate(
        model="gpt-image-1",
        prompt=wolf_prompt,
        size="1024x1024",
        quality=quality
    )

    image_base64 = result.data[0].b64_json
    image_bytes = base64.b64decode(image_base64)

    # オリジナルサイズで保存
    image_original = Image.open(BytesIO(image_bytes))
    image_original.save(original_path, format="JPEG", quality=95, optimize=True)

    # リサイズ版を保存
    image = Image.open(BytesIO(image_bytes))
    image = image.resize((250, 250), Image.LANCZOS)
    image.save(path, format="JPEG", quality=80, optimize=True)

# 品質比較画像を横に並べて表示
print("品質比較(横並び):")
comparison_img = Image.new('RGB', (750, 250), (255, 255, 255))
for i, path in enumerate(wolf_paths):
    img = Image.open(path)
    comparison_img.paste(img, (i * 250, 0))

comparison_path = "character_imgs/wolf_quality_comparison.jpg"
comparison_img.save(comparison_path, format="JPEG", quality=85, optimize=True)
display(IPImage(comparison_path))

print("\n個別画像:")
for i, quality in enumerate(qualities):
    print(f"{quality.capitalize()} quality:")
    display(IPImage(wolf_paths[i]))

画像編集とバリエーション

既存キャラクターの衣装変更

生成したキャラクターの衣装を変更してみましょう。

# 猫耳女性の衣装を変更
costume_change_prompt = """
この猫耳女性キャラクターの衣装を魔法使いの格好に変更してください:
- 紫の魔法使いローブと帽子
- 魔法の杖を持たせる
- 星や月の装飾
- 神秘的な雰囲気
- 元のキャラクターの顔と髪型は保持
"""

catgirl_wizard_path = "character_imgs/catgirl_wizard.jpg"
# 元の画像を読み込み(ファイルハンドルを適切に管理)
with open(catgirl_path, "rb") as f:
    catgirl_img_data = f.read()

# 一時的にファイルとして保存して編集
temp_catgirl_path = "character_imgs/temp_catgirl.jpg"
with open(temp_catgirl_path, "wb") as f:
    f.write(catgirl_img_data)

# 衣装変更
with open(temp_catgirl_path, "rb") as img_file:
    result_costume = client.images.edit(
        model="gpt-image-1",
        image=img_file,
        prompt=costume_change_prompt,
        size="1024x1536"
    )

# 画像を保存(オリジナルサイズとリサイズ版の両方)
image_base64 = result_costume.data[0].b64_json
image_bytes = base64.b64decode(image_base64)

# オリジナルサイズで保存
catgirl_wizard_original_path = "character_imgs/catgirl_wizard_original.jpg"
image_original = Image.open(BytesIO(image_bytes))
image_original.save(catgirl_wizard_original_path, format="JPEG", quality=95, optimize=True)

# リサイズ版を保存
image = Image.open(BytesIO(image_bytes))
image = image.resize((300, 450), Image.LANCZOS)
image.save(catgirl_wizard_path, format="JPEG", quality=85, optimize=True)

print("オリジナルサイズ:")
display(IPImage(catgirl_wizard_original_path))
print("リサイズ版:")
display(IPImage(catgirl_wizard_path))

複数キャラクターの組み合わせ

2つのキャラクターを組み合わせて、友達同士のシーンを作成してみましょう。

duo_prompt = """
猫耳女性と犬耳男性が一緒にいる友好的なシーンを作成してください:
- 2人が並んで立っている
- 明るく楽しい雰囲気
- 学校の屋上や公園などの背景
- 両キャラクターの特徴を保持
- アニメスタイル
- 友情を表現する自然なポーズ
"""

duo_path = "character_imgs/catgirl_dogboy_duo.jpg"
# 元の画像を読み込み(ファイルハンドルを適切に管理)
with open(catgirl_path, "rb") as f1:
    catgirl_data = f1.read()
with open(dogboy_path, "rb") as f2:
    dogboy_data = f2.read()

# 一時ファイルとして保存
temp_catgirl = "character_imgs/temp_catgirl_duo.jpg"
temp_dogboy = "character_imgs/temp_dogboy_duo.jpg"

with open(temp_catgirl, "wb") as f:
    f.write(catgirl_data)
with open(temp_dogboy, "wb") as f:
    f.write(dogboy_data)

# 両方の画像を参照として使用
with open(temp_catgirl, "rb") as f1, open(temp_dogboy, "rb") as f2:
    result_duo = client.images.edit(
        model="gpt-image-1",
        image=[f1, f2],
        prompt=duo_prompt,
        size="1536x1024"  # 横長で2人を表示
    )

# 画像を保存(オリジナルサイズとリサイズ版の両方)
image_base64 = result_duo.data[0].b64_json
image_bytes = base64.b64decode(image_base64)

# オリジナルサイズで保存
duo_original_path = "character_imgs/catgirl_dogboy_duo_original.jpg"
image_original = Image.open(BytesIO(image_bytes))
image_original.save(duo_original_path, format="JPEG", quality=95, optimize=True)

# リサイズ版を保存
image = Image.open(BytesIO(image_bytes))
image = image.resize((450, 300), Image.LANCZOS)
image.save(duo_path, format="JPEG", quality=85, optimize=True)

print("オリジナルサイズ:")
display(IPImage(duo_original_path))
print("リサイズ版:")
display(IPImage(duo_path))

高度なキャラクター生成

感情表現のバリエーション

まず、ベースとなるうさぎ耳女性キャラクターを生成し、それを元に感情表現を変化させてみましょう。

# ベースのうさぎ耳女性キャラクターを生成
rabbit_base_prompt = """
アニメスタイルのうさぎ耳女性キャラクター:
- 白いうさぎの耳(ピンクの内側)
- ピンクの瞳
- プラチナブロンドの髪
- 白いドレス
- 中立的な表情
- 高品質なアニメアート
"""

rabbit_base_path = "character_imgs/rabbit_girl_base.jpg"

result_base = client.images.generate(
    model="gpt-image-1",
    prompt=rabbit_base_prompt,
    size="1024x1024",
    quality="high"
)

# ベース画像を保存
image_base64 = result_base.data[0].b64_json
image_bytes = base64.b64decode(image_base64)

# オリジナルサイズで保存
rabbit_base_original_path = "character_imgs/rabbit_girl_base_original.jpg"
image_original = Image.open(BytesIO(image_bytes))
image_original.save(rabbit_base_original_path, format="JPEG", quality=95, optimize=True)

# リサイズ版を保存
image = Image.open(BytesIO(image_bytes))
image = image.resize((200, 200), Image.LANCZOS)
image.save(rabbit_base_path, format="JPEG", quality=80, optimize=True)

print("ベースキャラクター:")
display(IPImage(rabbit_base_path))
# ベース画像を使用して感情表現のバリエーションを生成
emotions = ["幸せ", "悲しい", "怒り", "驚き", "恥ずかしがり"]
emotion_paths = []

# ベース画像データを読み込み
with open(rabbit_base_original_path, "rb") as f:
    base_image_data = f.read()

for emotion in emotions:
    emotion_prompt = f"""
    このうさぎ耳女性キャラクターの表情を{emotion}の表情に変更してください。
    キャラクターの外見(髪型、衣装、耳など)は元のまま保持し、
    表情のみを{emotion}に変化させてください。
    高品質なアニメアート。
    """

    path = f"character_imgs/rabbit_girl_{emotion}.jpg"
    original_path = f"character_imgs/rabbit_girl_{emotion}_original.jpg"
    emotion_paths.append(path)

    # 一時ファイルとして保存
    temp_base_path = "character_imgs/temp_rabbit_base.jpg"
    with open(temp_base_path, "wb") as f:
        f.write(base_image_data)

    # 感情表現を変更
    with open(temp_base_path, "rb") as img_file:
        result = client.images.edit(
            model="gpt-image-1",
            image=img_file,
            prompt=emotion_prompt,
            size="1024x1024"
        )

    image_base64 = result.data[0].b64_json
    image_bytes = base64.b64decode(image_base64)

    # オリジナルサイズで保存
    image_original = Image.open(BytesIO(image_bytes))
    image_original.save(original_path, format="JPEG", quality=95, optimize=True)

    # リサイズ版を保存
    image = Image.open(BytesIO(image_bytes))
    image = image.resize((200, 200), Image.LANCZOS)
    image.save(path, format="JPEG", quality=80, optimize=True)

# 感情表現比較画像を横に並べて表示
print("感情表現比較(横並び):")
emotion_comparison_img = Image.new('RGB', (1200, 200), (255, 255, 255))

# ベース画像を最初に配置
base_img = Image.open(rabbit_base_path)
emotion_comparison_img.paste(base_img, (0, 0))

# 各感情画像を配置
for i, path in enumerate(emotion_paths):
    img = Image.open(path)
    emotion_comparison_img.paste(img, ((i + 1) * 200, 0))

emotion_comparison_path = "character_imgs/rabbit_emotion_comparison.jpg"
emotion_comparison_img.save(emotion_comparison_path, format="JPEG", quality=85, optimize=True)
display(IPImage(emotion_comparison_path))

print("\n個別画像:")
print("ベース:")
display(IPImage(rabbit_base_path))

for i, emotion in enumerate(emotions):
    print(f"{emotion}の表情:")
    display(IPImage(emotion_paths[i]))

季節テーマのキャラクター

季節に合わせたキャラクターを生成し、最後に4つの季節を統合した画像も作成してみましょう。

seasons = {
    "春": "桜の花びらと緑の新芽、淡いピンクの衣装",
    "夏": "海辺とひまわり、明るい青い水着",
    "秋": "紅葉と落ち葉、暖かいオレンジのセーター",
    "冬": "雪と氷、白いコートとマフラー"
}

seasonal_paths = []
seasonal_original_paths = []

for season, description in seasons.items():
    seasonal_prompt = f"""
    {season}をテーマにした猫耳女性キャラクター:
    - {description}
    - {season}らしい背景
    - {season}の色合い
    - 季節に合った表情と雰囲気
    - 高品質なアニメアート
    """

    path = f"character_imgs/catgirl_{season}.jpg"
    original_path = f"character_imgs/catgirl_{season}_original.jpg"
    seasonal_paths.append(path)
    seasonal_original_paths.append(original_path)

    result = client.images.generate(
        model="gpt-image-1",
        prompt=seasonal_prompt,
        size="1024x1024",
        quality="high"
    )

    image_base64 = result.data[0].b64_json
    image_bytes = base64.b64decode(image_base64)

    # オリジナルサイズで保存
    image_original = Image.open(BytesIO(image_bytes))
    image_original.save(original_path, format="JPEG", quality=95, optimize=True)

    # リサイズ版を保存
    image = Image.open(BytesIO(image_bytes))
    image = image.resize((250, 250), Image.LANCZOS)
    image.save(path, format="JPEG", quality=80, optimize=True)

# 4つの季節を統合した比較画像を作成
print("四季比較(横並び):")
seasonal_comparison_img = Image.new('RGB', (1000, 250), (255, 255, 255))

for i, path in enumerate(seasonal_paths):
    img = Image.open(path)
    seasonal_comparison_img.paste(img, (i * 250, 0))

seasonal_comparison_path = "character_imgs/catgirl_seasonal_comparison.jpg"
seasonal_comparison_img.save(seasonal_comparison_path, format="JPEG", quality=85, optimize=True)
display(IPImage(seasonal_comparison_path))

# 4つの季節を統合した1つの画像も生成
print("\n4つの季節を統合した特別な画像:")
unified_seasonal_prompt = """
四季を表現する猫耳女性キャラクターの統合画像:
- 中央に1人の猫耳女性キャラクター
- 背景が4つの季節に分割されている(春夏秋冬)
- キャラクターの衣装も4つの季節の要素を組み合わせ
- 春:桜の花びら、夏:ひまわり、秋:紅葉、冬:雪
- 神秘的で美しい合成的な雰囲気
- 高品質なアニメアート
"""

unified_seasonal_path = "character_imgs/catgirl_unified_seasons.jpg"
unified_seasonal_original_path = "character_imgs/catgirl_unified_seasons_original.jpg"

result_unified = client.images.generate(
    model="gpt-image-1",
    prompt=unified_seasonal_prompt,
    size="1536x1024",  # 横長で四季を表現
    quality="high"
)

image_base64 = result_unified.data[0].b64_json
image_bytes = base64.b64decode(image_base64)

# オリジナルサイズで保存
image_original = Image.open(BytesIO(image_bytes))
image_original.save(unified_seasonal_original_path, format="JPEG", quality=95, optimize=True)

# リサイズ版を保存
image = Image.open(BytesIO(image_bytes))
image = image.resize((400, 267), Image.LANCZOS)
image.save(unified_seasonal_path, format="JPEG", quality=85, optimize=True)

display(IPImage(unified_seasonal_path))

print("\n個別の季節テーマ:")
for i, (season, description) in enumerate(seasons.items()):
    print(f"{season}テーマ:")
    display(IPImage(seasonal_paths[i]))

ストリーミング生成

リアルタイムで画像生成過程を見ながらキャラクターを作成してみましょう。

streaming_prompt = """
神秘的な月の光に照らされた狐耳の魔法使い女性:
- 長い銀髪と金色の瞳
- エレガントな青い魔法使いローブ
- 魔法の杖と浮遊する魔法陣
- 月明かりの森の背景
- 魔法的で幻想的な雰囲気
- 高品質なアニメアート
"""

streaming_path = "character_imgs/fox_mage_streaming"
# ストリーミング生成
stream = client.images.generate(
    model="gpt-image-1",
    prompt=streaming_prompt,
    size="1024x1024",
    quality="high",
    stream=True,
    partial_images=2  # 中間画像を2枚受信
)

partial_count = 0
for event in stream:
    if hasattr(event, 'data') and len(event.data) > 0:
        if hasattr(event.data[0], 'b64_json'):
            # 最終画像
            image_base64 = event.data[0].b64_json
            image_bytes = base64.b64decode(image_base64)

            image = Image.open(BytesIO(image_bytes))
            image = image.resize((300, 300), Image.LANCZOS)
            final_path = f"{streaming_path}_final.jpg"
            image.save(final_path, format="JPEG", quality=85, optimize=True)

            print("最終画像:")
            display(IPImage(final_path))
        elif hasattr(event.data[0], 'partial_image_b64'):
            # 中間画像
            partial_count += 1
            image_base64 = event.data[0].partial_image_b64
            image_bytes = base64.b64decode(image_base64)

            image = Image.open(BytesIO(image_bytes))
            image = image.resize((300, 300), Image.LANCZOS)
            partial_path = f"{streaming_path}_partial_{partial_count}.jpg"
            image.save(partial_path, format="JPEG", quality=85, optimize=True)

            print(f"中間画像 {partial_count}:")
            display(IPImage(partial_path))

生成されたキャラクターのギャラリー

最後に、生成したすべてのキャラクターをまとめて表示してみましょう。

# 生成されたすべての画像を表示
import glob

print("=== キャラクターギャラリー ===")
image_files = glob.glob("character_imgs/*.jpg") + glob.glob("character_imgs/*.png")

for img_path in sorted(image_files):
    filename = img_path.split("/")[-1]
    print(f"\n{filename}:")
    display(IPImage(img_path))

まとめとコツ

このクックブックでは、GPT Imageを使用して様々な動物耳キャラクターを生成する方法を学びました。

効果的なプロンプトのコツ:

  1. 具体的な詳細を含める: 髪の色、瞳の色、衣装の詳細など
  2. スタイルを指定: 「アニメスタイル」「高品質なアニメアート」など
  3. 感情や雰囲気を表現: キャラクターの性格や感情を明確に
  4. 背景の指定: キャラクターに合った背景を指定
  5. 品質の要求: 「詳細な」「高品質な」などの修飾語を使用

Google Colab環境での活用:

  • ブラウザ上で直接実行できる手軽さ
  • 生成した画像をすぐに確認・保存可能
  • バッチ処理での複数キャラクター生成
  • 透明背景での素材作成

このクックブックを基に、オリジナルキャラクターの創作や、ゲーム・アニメーション用の素材作成など、様々な用途でGPT Imageを活用してください!

楽しいキャラクター生成を!

📒ノートブック

Google Colab

参考サイト

openai-cookbook/examples/Generate_Images_With_GPT_Image.ipynb at main · openai/openai-cookbook
Examples and guides for using the OpenAI API. Contribute to openai/openai-cookbook development by creating an account on GitHub.
Generate images with GPT Image | OpenAI Cookbook
In this cookbook, you'll learn how to use GPT Image, our new large language model with image generation capabilities. This model has worl...
Just a moment...

コメント

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