🖼️

Azure OpenAI ServiceでGPT-Image-1を使って画像生成を試してみた

に公開

最近 Azure OpenAI ServiceGPT-Image-1 という画像生成モデルが限定プレビューで追加されたと聞き、早速試してみました。ドキュメントを読みつつなんとか動かしてみたので、内容を書いてみます。

申請まだの方👇
https://customervoice.microsoft.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbR7en2Ais5pxKtso_Pz4b1_xUQ1VGQUEzRlBIMVU2UFlHSFpSNkpOR0paRSQlQCN0PWcu

概要をつかみたい方👇
https://youtu.be/btA8njJjLXY

GPT-Image-1とは?

GPT-Image-1 は、Azure OpenAI Serviceで提供されている最新の画像生成モデルです。テキストで指示したプロンプトから高品質な画像を生成してくれるモデルで、現在は 限定公開プレビュー として提供されています。利用するには事前に申し込みを行い、Microsoftからアクセス承認を得た上でAzure上にデプロイする必要があります。

公式の発表によれば、GPT-Image-1は従来のDALL-Eモデルの強みを引き継ぎつつ、さらに詳細な指示への応答性能や画像内テキストの描画能力が向上しているとのことです。具体的には、以下のような機能・特徴が挙げられています。

  • テキスト to 画像生成 : テキストのプロンプトから直接画像を生成
  • 画像 to 画像生成: アップロードした画像とテキスト指示から新しい画像を生成
  • テキストによる画像編集: 既存の画像にテキストプロンプトで編集を加える
  • インペインティング: 画像の一部を選択して別内容に差し替える

画像出力のカスタマイズ

gpt-image-1では、以下の出力オプションをカスタマイズできます。

設定項目 説明
サイズ (Size) 画像の寸法(例:1024×1024、1024×1536など)
品質 (Quality) レンダリング品質(low、medium、high)
フォーマット (Format) 出力ファイル形式(png、jpeg、webp)
圧縮率 (Compression) JPEGまたはWebP形式での圧縮率(0〜100%)
背景 (Background) 背景の設定(透明または不透明)

size, quality, backgroundauto オプションにも対応しており、プロンプトに基づいてモデルが最適な設定を自動選択します。

サイズと品質のオプション

標準品質の正方形画像(1024×1024)は最も高速に生成できます。
デフォルトのサイズは 1024×1024ピクセル です。

利用可能なサイズ

サイズ 説明
1024×1024 正方形(スクエア)
1536×1024 横長(ランドスケープ)
1024×1536 縦長(ポートレート)
auto プロンプトに応じて自動選択(デフォルト)

品質オプション

品質 説明
low 低品質(速い)
medium 中品質(標準)
high 高品質(遅いが高精細)
auto プロンプトに応じて自動選択(デフォルト)

出力フォーマット

Image APIのレスポンスは、Base64エンコードされた画像データを返します。
デフォルトのフォーマットは png ですが、jpeg または webp 形式も選択可能です。

圧縮について

JPEGまたはWebP形式を使用する場合、output_compression パラメータで圧縮率(0〜100%)を指定できます。
例:output_compression=50 と指定すると、画像が50%圧縮されます。

透明背景(Transparency)

gpt-image-1は透明背景をサポートしています。
透明にしたい場合は、background パラメータを transparent に設定してください。

※透明背景が使えるのは、png または webp 形式を選んだ場合のみです。

制限事項とコンテンツモデレーション

gpt-image-1(GPT-4o Imageモデル)は非常に強力かつ多用途な画像生成モデルですが、いくつかの制限事項も存在します。

制限事項

項目 説明
レイテンシ (Latency) 複雑なプロンプトの場合、処理に最大2分かかることがあります。
テキスト描画 (Text Rendering) DALL·Eシリーズより大幅に改善されていますが、正確なテキスト配置や明瞭さには依然課題があります。
一貫性 (Consistency) イメージ全体の一貫性は高いものの、複数回の生成でキャラクターやブランド要素を完全に統一するのが難しい場合があります。
構図コントロール (Composition Control) 指示に対する追従性は向上していますが、レイアウト感度の高い構図で要素を正確に配置するのは難しい場合があります。

安全対策について

GPT-image-1 は、**OpenAIが提供する安全対策(セーフティスタック)**の上に構築されています。
このセーフティスタックには、
-C2PA(デジタル透かしなどによるコンテンツの真正性確認)
-入力/出力モデレーション(プロンプトや生成画像をチェックして、不適切な内容を防ぐ仕組み)
が含まれています。
すべてのプロンプトおよび生成画像は、コンテンツポリシーに基づいてフィルタリングされます。

gpt-image-1を使用した画像生成では、moderation パラメータによってモデレーションの厳しさを制御できます。

パラメータ値 説明
auto(デフォルト) 特定カテゴリ(年齢制限が必要なコンテンツなど)の生成を制限する標準フィルタリング。
low より緩やかなフィルタリング。制限が少ない設定。

さらに、Azure AI特有 の追加機能として、以下も実施されています。

  • コンテンツの安全性管理(Content Safety)
  • 不正使用の監視(Abuse Monitoring)

GitHubのサンプルコードで試してみる

GPT-Image-1の概要が分かったところで、実際にAzure環境で画像生成を試してみました。
以下を参考
https://github.com/guygregory/gpt-image-1/

早速デプロイしてみます。
Azure OpenAI Serviceでは、West US 3 (Global Standard)UAE North (Global Standard) のみでデプロイ可能です。
また、デフォルトクオータは以下のようです。

制限名 制限値
デフォルトのGPT-image-1クォータ制限 2キャパシティユニット: 1分あたり6リクエスト
env
# Configuration for AzureOpenAI
AZURE_OPENAI_API_IMAGE_KEY = "<YOUR AZURE OPENAI KEY>"
AZURE_OPENAI_API_IMAGE_ENDPOINT = "https://<YOUR ENDPOINT>.openai.azure.com/"
AZURE_OPENAI_API_IMAGE_MODEL = "gpt-image-1"
AZURE_OPENAI_API_VERSION = "2025-04-01-preview"
generate-gradio
import io
import base64
import os
from dotenv import load_dotenv
from openai import OpenAI, AzureOpenAI
from PIL import Image
import gradio as gr

# Load environment variables from .env file
load_dotenv()

# 使用するAIホストを設定します(AzureOpenAI または OpenAI)
AIhost = "AzureOpenAI" # "AzureOpenAI" または "OpenAI" に設定します

def get_client(host: str):
    """
    Returns the deployment and client based on the specified host.
    Exits the application if an unsupported host is provided.
    """
    if host == "AzureOpenAI":
        deployment = os.environ["AZURE_OPENAI_API_IMAGE_MODEL"]
        client = AzureOpenAI(
            api_key=os.environ["AZURE_OPENAI_API_IMAGE_KEY"],
            api_version=os.environ["AZURE_OPENAI_API_VERSION"],
            azure_endpoint=os.environ["AZURE_OPENAI_API_IMAGE_ENDPOINT"]
        )
    elif host == "OpenAI":
        deployment = "gpt-image-1"  # Default deployment for OpenAI
        client = OpenAI()
    else:
        print("Invalid AI host specified. Please set AIhost to 'AzureOpenAI' or 'OpenAI' and provide the configuration in the .env file")
        exit(0)
    return deployment, client

# AIホストに応じたデプロイメントとクライアントを取得します
deployment, client = get_client(AIhost)

def generate_image(
    prompt: str,
    background: str,
    moderation: str,
    output_compression: int,
    output_format: str,
    quality: str,
    size: str
):
    # images.generateエンドポイントを呼び出します
    result = client.images.generate(
        model="gpt-image-1",
        prompt=prompt,
        background=background,                 # 背景:transparent(透明)、opaque(不透明)、auto(自動)
        moderation=moderation,                 # モデレーション:low(低制限)またはauto(自動)
        output_compression=output_compression, # 出力圧縮率(0〜100)
        output_format=output_format,           # png, jpeg, or webp
        quality=quality,                       # 画質:auto(自動)、high(高品質)、medium(中品質)、low(低品質)
        size=size                              # サイズ:1024x1024、1536x1024、1024x1536、またはauto(自動)
    )
    # Base64エンコードされた画像データをデコードしてPIL画像として返します
    image_bytes = base64.b64decode(result.data[0].b64_json)
    return Image.open(io.BytesIO(image_bytes))


# Gradioでインターフェースを作成します
with gr.Blocks(title="OpenAI Image Generator") as demo:
    with gr.Row():
        #  左側:生成された画像を表示
        with gr.Column():
            img_output = gr.Image(label="Generated Image", type="pil")

        # 右側:プロンプト入力 ➔ パラメータ設定 ➔ 送信ボタン
        with gr.Column():
            gr.Markdown("## Prompt")  # Add this line for styled label
            prompt_input = gr.Textbox(
                label="",  # Hide default label
                placeholder="Enter your image prompt here…",
                lines=2,
                max_length=32000,         # Set max length to 32000
                container=False
            )
            submit_btn = gr.Button("Submit")

            gr.Markdown("## Parameters")
            background_input = gr.Radio(
                choices=["transparent", "opaque", "auto"],
                value="auto",
                label="Background"
            )
            moderation_input = gr.Radio(
                choices=["low", "auto"],
                value="auto",
                label="Moderation"
            )
            output_compression_input = gr.Slider(
                minimum=0, maximum=100, step=1,
                value=100,
                label="Output Compression (for jpeg/webp only)",
                interactive=False  #  初期状態では無効(png選択時)
            )
            output_format_input = gr.Radio(
                choices=["png", "jpeg", "webp"],
                value="png",
                label="Output Format"
            )
            quality_input = gr.Radio(
                choices=["auto", "high", "medium", "low"],
                value="auto",
                label="Quality"
            )
            size_input = gr.Dropdown(
                choices=["1024x1024", "1536x1024", "1024x1536", "auto"],
                value="auto",
                label="Size"
            )

    # Wire up the button
    submit_btn.click(
        fn=generate_image,
        inputs=[
            prompt_input,
            background_input,
            moderation_input,
            output_compression_input,
            output_format_input,
            quality_input,
            size_input
        ],
        outputs=img_output
    )

    # 出力形式がjpegまたはwebpの場合、圧縮率スライダーを有効化
    def update_output_compression_interactive(output_format):
        if output_format in ["jpeg", "webp"]:
            return gr.update(interactive=True)
        else:
            return gr.update(interactive=False)

    # 出力形式が変更された時に圧縮率スライダーの状態を更新
    output_format_input.change(
        fn=update_output_compression_interactive,
        inputs=output_format_input,
        outputs=output_compression_input
    )

# プログラムを起動します
if __name__ == "__main__":
    demo.launch()

実際のデプロイした後の画面

各種設定値が手動で選べるようになっていていいですね。
ただし、画像のアップロードには対応していないようです。

試した結果

最近バズっている、ジブリ風です。
なぜかヘルメットはHONDAでした。

プロンプト:F1レーサーを躍動感あるように描いて。その際にジブリ風にして。

ほかにも私が大好きなドラゴンボール風になりました。
作風的に走ってる方がしっくりきます。

プロンプト:F1レーサーを躍動感あるように描いて。その際にドラゴンボール風にして。

コストとレイテンシについて

このモデル(gpt-image-1)は、まず画像専用のトークンを生成することで画像を作成します。
レイテンシ(応答時間)と最終的なコストは、画像をレンダリングするために必要なトークン数に比例します。
つまり、画像サイズが大きくなったり、品質設定が高くなると、より多くのトークンが必要になり、コストや遅延が増加します。

画像のサイズ品質によって生成されるトークン数は以下の通りです。

品質 正方形 (1024×1024) 縦長 (1024×1536) 横長 (1536×1024)
低 (Low) 272 トークン 408 トークン 400 トークン
中 (Medium) 1056 トークン 1584 トークン 1568 トークン
高 (High) 4160 トークン 6240 トークン 6208 トークン

最後

参考にしたリソースはこちら
https://azure.microsoft.com/en-us/blog/unveiling-gpt-image-1-rising-to-new-heights-with-image-generation-in-azure-ai-foundry/?msockid=00c7e3abb4ad6fc13ff8f6eeb5d76efb

https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/dall-e?tabs=gpt-image-1

https://platform.openai.com/docs/guides/image-generation?image-generation-model=gpt-image-1

https://github.com/guygregory/gpt-image-1/

Discussion