🖼️

OpenAI gpt-image-1 で複数画像を合成

に公開

gpt image 1

OpenAIの gpt-image-1 モデルを使って、複数の画像を組み合わせて新しい画像を生成する機能を試してみました。


1. 公式ドキュメントを確認

まずは公式ドキュメントで機能の概要を確認します。

Create a new image using image references

You can use one or more images as a reference to generate a new image.

: 画像参照を使用して新しい画像を作成できます。1つ以上の画像を参照として使用可能です。

📘 Image generation guide | OpenAI Platform Docs

複数の参照画像を渡すだけで、それらを組み合わせた画像を生成できるようです。


2. サンプルコードを実行

ドキュメントのサンプルコードを main.py に保存します。

import base64
from openai import OpenAI

client = OpenAI()

prompt = """
Generate a photorealistic image of a gift basket on a white background
labeled 'Relax & Unwind' with a ribbon and handwriting-like font,
containing all the items in the reference pictures.
"""

result = client.images.edit(
    model="gpt-image-1",
    image=[
        open("body-lotion.png", "rb"),
        open("bath-bomb.png", "rb"),
        open("incense-kit.png", "rb"),
        open("soap.png", "rb"),
    ],
    prompt=prompt
)

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

# Save the image to a file
with open("gift-basket.png", "wb") as f:
    f.write(image_bytes)

3. Streamlit化を依頼

毎回コードを書き換えるのは手間なので、Claude Codeに依頼をして、Streamlitアプリへ書き換えてもらいました。
このアプリを通して、プロンプトと画像を入れ替えて色々試してみましょう。

プロンプト

@main.py を以下の要件に従って変更してください。
- Streamlitで起動
- テキストエリアからの入力をpromptに設定
- UIで選択した複数画像をimage配列に設定
- API Keyは.envを使用

完成したコード

import streamlit as st
import base64
from openai import OpenAI
import os
from dotenv import load_dotenv
from io import BytesIO
from PIL import Image
from datetime import datetime

load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

st.title("GPT-IMAGE-1 画像合成")

prompt = st.text_area("プロンプト", height=150)
uploaded_files = st.file_uploader(
    "参照画像をアップロード",
    type=['png', 'jpg', 'jpeg'],
    accept_multiple_files=True,
)
button_enabled = prompt and uploaded_files
generate_button = st.button(
    "画像生成", type="primary", use_container_width=True, disabled=not button_enabled
)

st.subheader("参照画像")
if uploaded_files:
    num_cols = min(len(uploaded_files), 2)
    img_cols = st.columns(num_cols)
    for i, uploaded_file in enumerate(uploaded_files):
        with img_cols[i % num_cols]:
            image = Image.open(uploaded_file)
            st.image(image, caption=f"画像 {i+1}", use_container_width=True)
else:
    st.info("画像をアップロードしてください")

st.markdown("---")

st.subheader("生成結果")
if generate_button and prompt and uploaded_files:
    try:
        with st.spinner("画像を生成中..."):
            image_files = []
            for uploaded_file in uploaded_files:
                uploaded_file.seek(0)
                image_files.append(uploaded_file)

            result = client.images.edit(
                model="gpt-image-1",
                image=image_files,
                prompt=prompt,
                input_fidelity="high"
            )

            image_base64 = result.data[0].b64_json
            image_bytes = base64.b64decode(image_base64)
            generated_image = Image.open(BytesIO(image_bytes))
            st.image(generated_image, caption="生成された画像", use_container_width=True)

            timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
            st.download_button(
                label="画像をダウンロード",
                data=image_bytes,
                file_name=f"generated_{timestamp}.png",
                mime="image/png"
            )
            st.success("画像生成が完了しました!")
    except Exception as e:
        st.error(f"エラーが発生しました: {str(e)}")
else:
    st.info("「画像生成」をクリックしてください")

気を抜くとDALL-Eを使おうとするので、何度か再生成しました。


4. 実行結果

ブラウザでプロンプト入力と画像アップロードができるようになりました!

アプリの画面例

生成ボタンをクリックすると、合成結果が表示されます。


5. 合成実験

Unsplashの写真をお借りして、様々な画像合成を試してみました。

例1

プロンプト

ボトルのラベルを小鳥に変更してください。
イラストのタッチや色合いなどのスタイルは元のラベルイラストを維持してください。

参照画像

茶色と白のラベルのボトル 茶色の木製の柵に茶色と白の鳥
Reference 1 Reference 2

実行結果
generated_20251011004537

コメント
イラストに色が付いているけど、雰囲気のあるタッチですね。
ボトルの形状やハイライトが若干変わっているものの、違和感は無いです。


例2

プロンプト

写真のクッキーの一部をハムスターのクッキーに入れ替えてください。
風合いやデコレーションのテイストは揃えてください。

参照画像

茶色と白の木製文字 T 茶色のハムスター
Reference 1 Reference 2

実行結果
generated_20251011010640

コメント
立体感がありすぎてリアル寄りな感じだけど、質感は良いですね。
ヒゲがクッキーっぽくないかなぁ


例3

プロンプト

人形の顔、背景、レイアウトは維持したままで、新しい服を着せてください。

参照画像

ピンクのバイクに乗ったバービー人形 赤いドレスを着た女性
Reference 1 Reference 2

実行結果
generated_20251011094004

コメント
体型が近いせいか、自然な仕上がりです。
顔つきは、若干の違いでも結構目に付きますね。


例4

プロンプト

人形の顔、背景、レイアウトは維持したままで、新しい服を着せてください。

参照画像

白と青のクマのぬいぐるみ 赤いドレスを着た女性
Reference 1 Reference 2

実行結果
generated_20251011234006

コメント
同じプロンプトで、対象を変えてみました。
精一杯がんばってくれたと思います!


例5

プロンプト

ペンギンのロボットを描いて

参照画像

グレーとオレンジのロボット 岩の上に立つペンギンのグループ
Reference 1 Reference 2

実行結果
generated_20251012003639

コメント
こんな短文のプロンプトでも、それなりの仕上がりになりました。
手足もちゃんとペンギンになってる


例6

プロンプト

全ての座席に1つずつぬいぐるみを座らせてください。ぬいぐるみの数とバリエーションを増やしてください。

参照画像

茶色の椅子のグラフィック 茶色の干し草に白いウサギのぬいぐるみ
Reference 1 Reference 2

実行結果
generated_20251012233212

コメント
椅子の位置取りに苦労しているようで、なかなか精度が上がらず何度か画像生成しました。カエルのぬいぐるみがかわいい。
耳が3つあるやつがいるな…


例7

プロンプト

ガラス瓶のキャップを外して、花束の花を生けてください。

参照画像

ボトルと植物をトッピングした白いマント 赤と白の花束
Reference 1 Reference 2

実行結果
generated_20251014104045

コメント

瓶の形と位置が変わっていますが、全体的に良い仕上がりです。
特に指定しなくても水が入ってますね。(入ってないのもあるけど)


例8

プロンプト

全員を自然なポーズでベンチに座らせてください。

参照画像

茶色の土に茶色の木製ベンチ 茶色の干し草に白いウサギのぬいぐるみ
Reference 1 Reference 2
グレーとオレンジのロボット 白と青のクマのぬいぐるみ
Reference 3 Reference 4

実行結果

generated_20251014185441

コメント
参照画像の数を増やしてみました。
簡単な指示でも、もれなく合成されています


所感

適当なプロンプトを書いても、それなりの結果を出力してくれました。
プロンプトの解釈能力が優秀なのでしょうね。詳細な指示を出せば更に精度があがるのかな?
ただし、処理時間が60〜120秒と長いことと、トークン消費かかなり多いため、サービスへの組み込みは選定と工夫が必要になりそうです。

Discussion