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?

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

Posted at

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

前回の記事

セットアップ

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を活用してください!

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

📒ノートブック

参考サイト

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?