Databricksでgpt-image-1モデルを動かしてみる

こちらのクックブックをウォークスルーします。

https://cookbook.openai.com/examples/generate_images_with_gpt_image

# 準備

初めて使おうとした際に、以下のようなエラーに遭遇しました。

> PermissionDeniedError: Error code: 403 - {'error': {'message': 'Your organization must be verified to use the model `gpt-image-1`. Please go to: https://platform.openai.com/settings/organization/general and click on Verify Organization. If you just verified, it can take up to 15 minutes for access to propagate.', 'type': 'invalid_request_error', 'param': None, 'code': None}}

組織の検証が必要とのことです。

リンク先にアクセスしてVerificationのボタンを押します。免許書などのIDや顔を撮影して認証を受けます。Organization Verifiedになったら、メッセージの通り15分くらい待ちました。

![スクリーンショット 2025-05-19 20.45.34.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/72ff7602-e5da-4b7f-86b7-13c3c89479c2.jpeg)

# ウォークスルー

このクックブックでは、画像生成機能を備えた新しい大規模言語モデルであるGPT Imageの使い方を学びます。

このモデルは世界の知識を持ち、この広範な理解を活用して画像を生成することができます。また、以前の世代の画像モデルであるDallE 2および3と比較して、指示に従う能力やフォトリアリスティックな画像を生成する能力が大幅に向上しています。

画像生成について詳しくは、[ガイド](https://platform.openai.com/docs/guides/image-generation?image-generation-model=gpt-image-1)をご参照ください。

## セットアップ

```py
%pip install -U openai
dbutils.library.restartPython()
```

```py
import os
os.environ["OPENAI_API_KEY"] = dbutils.secrets.get(scope="demo-token-takaaki.yayoi", key="openai_api_key")
```

```py
import base64
import os
from openai import OpenAI
from PIL import Image
from io import BytesIO
from IPython.display import Image as IPImage, display
```

```py
client = OpenAI()
```

```py
# Create imgs/ folder
folder_path = "imgs"
os.makedirs(folder_path, exist_ok=True)
```

## 画像の生成

GPT Image 1は指示に従うのが得意で、非常に詳細な指示でモデルに画像を生成させることができます。

```py
prompt1 = """
このキャラクターのリアルな画像をレンダリングしてください：
ブロビーエイリアンキャラクター
名前: グロプタック (ニックネーム: "グロープ")
視覚的外観
体の形: 無定形でゼラチン状。全体のシルエットは涙滴や溶けたマシュマロに似ており、時間とともに少しずつ変化します。感情的になったり驚いたりするときに潰れたり伸びたりします。
素材の質感: 半透明で生物発光するゼリーのような揺れ。速く動いたりコミュニケーションを取るときに表面が時折波打ちます。
カラーパレット:
- ベース: イリデッセントラベンダーまたはシーフォームグリーン
- アクセント: ネオンピンク、エレクトリックブルー、またはゴールデンイエローのサブサーフェスグローイングベイン
- 感情に基づく色の変化 (怒り = ダークレッド、喜び = 明るいアクア、恐怖 = 淡いグレー)
顔の特徴:
- 目: 3～5個の非対称の浮遊する球体が内部にあり、独立して回転したり瞬きしたりします
- 口: オプション—話したり感情を表現したりするときに表面に現れる波打つ三日月形
- 目に見える鼻や耳はなく、ゼリーに埋め込まれた振動感知受容体を使用します
- 四肢: 通常はありませんが、相互作用や移動のために必要に応じて仮足（触手のような四肢）を伸ばすことができます。仮の足や手を一時的に現すことができます。
動きと行動
移動方法:
- 滑ったり、跳ねたり、転がったりします。
- 吸盤を使って壁や天井にくっつくことができます。怖がると、平らになって素早く逃げることがあります。
仕草:
- 休んでいるときでも常に揺れたり波打ったりします
- 無害な発光するスライムの跡を残します
- 好奇心から近くの小さな物体を一時的に吸収する傾向があります
"""

img_path1 = "imgs/glorptak.jpg"
```

```py
# 画像の生成
result1 = client.images.generate(
    model="gpt-image-1",
    prompt=prompt1,
    size="1024x1024"
)
```

```py
# 画像をファイルに保存し、ファイルサイズを小さくするためにリサイズ/圧縮
image_base64 = result1.data[0].b64_json
image_bytes = base64.b64decode(image_base64)

# 高品質のグロプタックが必要な場合は、ここを調整してください
image = Image.open(BytesIO(image_bytes))
image = image.resize((300, 300), Image.LANCZOS)
image.save(img_path1, format="JPEG", quality=80, optimize=True)
```

```py
# 結果を表示
display(IPImage(img_path1))
```

おおー。


![download.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/ec8690ac-9705-4bea-90c5-e1e978e0033b.jpeg)

## 出力のカスタマイズ

以下の出力プロパティをカスタマイズできます：

- 品質は`low`、`medium`、`high`、または`auto`（デフォルト値）に設定できます
- サイズは`1024x1024`（正方形）、`1536x1024`（縦長）、`1024x1536`（横長）、または`auto`（デフォルト）に設定できます
- JPEGおよびWEBP形式の圧縮レベル（0-100%）を調整できます
- 透明な背景で画像を生成することができます（PNGまたはWEBPのみ対応）


```py
prompt2 = "暗い背景に金髪の女性として服を着た灰色のタビー猫のピクセルアートスタイルの肖像画を生成してください。"
img_path2 = "imgs/cat_portrait_pixel.jpg"
```

```py
# 画像を生成
result2 = client.images.generate(
    model="gpt-image-1",
    prompt=prompt2,
    quality="low",
    output_compression=50,
    output_format="jpeg",
    size="1024x1536"
)
```

```py
# 画像をファイルに保存し、ファイルサイズを小さくするためにリサイズ/圧縮
image_base64 = result2.data[0].b64_json
image_bytes = base64.b64decode(image_base64)

image = Image.open(BytesIO(image_bytes))
image = image.resize((250, 375), Image.LANCZOS)
image.save(img_path2, format="JPEG", quality=80, optimize=True)
```

```py
# 結果を表示
display(IPImage(img_path2))
```

![download (1).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/518ec654-b328-42b5-81c2-7af0606387e8.jpeg)

## 透明な背景

`background`プロパティを使用して透明な背景をリクエストできますが、プロンプトに透明な背景を指定すると、デフォルトで`transparent`に設定されます。

```py
prompt3 = "透明な背景に緑のバケットハットとピンクの羽根を持つピクセルアートスタイルの画像を生成してください。"
img_path3 = "imgs/hat.png"
```

```py
result3 = client.images.generate(
    model="gpt-image-1",
    prompt=prompt3,
    quality="low",
    output_format="png",
    size="1024x1024"
)
image_base64 = result3.data[0].b64_json
image_bytes = base64.b64decode(image_base64)
```

```py
# 画像をファイルに保存し、ファイルサイズを小さくするためにリサイズ/圧縮する
image_base64 = result3.data[0].b64_json
image_bytes = base64.b64decode(image_base64)

image = Image.open(BytesIO(image_bytes))
image = image.resize((250, 250), Image.LANCZOS)
image.save(img_path3, format="PNG")
```

```py
# 結果を表示する
display(IPImage(img_path3))
```
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/e9217e95-b518-4ccb-891c-ff1d7eb54e7a.png)

## 画像の編集

GPT Imageは画像入力を受け付け、それらを使用して新しい画像を作成することもできます。また、入力画像の特定の部分を変更したくない場合は、マスクを提供することもできます。

最大10枚の入力画像を使用でき、マスクを使用する場合は、`image`配列で提供された最初の画像に適用されます。

```py
prompt_edit = """
猫と帽子の画像を組み合わせて、木にとまっている猫が帽子をかぶっている様子をピクセルアートスタイルで表示してください。
"""
img_path_edit = "imgs/cat_with_hat.jpg"
```

```py
img1 = open(img_path2, "rb")
img2 = open(img_path3, "rb")
```

```py
# 新しい画像を生成する
result_edit = client.images.edit(
    model="gpt-image-1",
    image=[img1,img2], 
    prompt=prompt_edit,
    size="1024x1536"
)
```

```py
# 画像をファイルに保存し、ファイルサイズを小さくするためにリサイズ/圧縮する
image_base64 = result_edit.data[0].b64_json
image_bytes = base64.b64decode(image_base64)

image = Image.open(BytesIO(image_bytes))
image = image.resize((250, 375), Image.LANCZOS)
image.save(img_path_edit, format="JPEG", quality=80, optimize=True)
```

```py
# 結果を表示する
display(IPImage(img_path_edit))
```

合成されました。羽を手に持っているのが面白い。

![download (2).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f1d1240e-eeb1-4cbc-ae8e-7b3047941614.jpeg)

## マスクによる画像の編集

入力画像と一緒にマスクを提供することもできます（複数ある場合、マスクは最初の画像に適用されます）。これにより、マスクで覆われていない部分のみを編集します。モデルはマスク内の一部の画像を編集することがありますが、それを避けるようにします。

:::note info
**重要な注意点:** マスクにはアルファチャネルが含まれている必要があります。例えば、画像編集ソフトウェアを使用して手動で生成する場合、このアルファチャネルを含めるようにしてください。
:::


### マスクの生成

この例では、モデルを使用してマスクを自動的に生成します。マスクは完全ではないかもしれませんが、目的には十分です。正確なマスクが必要な場合は、画像セグメンテーションモデルを使用してください。

```py
img_path_mask = "imgs/mask.png"
prompt_mask = "画像内のキャラクター全体を区切るマスクを生成し、キャラクターがある部分を白、背景を黒にします。入力画像と同じサイズの画像を返します。"
```

```py
img_input = open(img_path1, "rb")

# マスクを生成する
result_mask = client.images.edit(
    model="gpt-image-1",
    image=img_input, 
    prompt=prompt_mask
)
```

```py
# 画像をファイルに保存し、ファイルサイズを小さくするためにリサイズ/圧縮する
image_base64 = result_mask.data[0].b64_json
image_bytes = base64.b64decode(image_base64)

image = Image.open(BytesIO(image_bytes))
image = image.resize((300, 300), Image.LANCZOS)
image.save(img_path_mask, format="PNG")
```

```py
# マスクを表示する
display(IPImage(img_path_mask))
```

プロンプトでマスクも作れてしまいます。

![download (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1405935c-490b-4e32-87c4-3bc856207d1f.png)

元の画像とほとんど同じ形状。

![download.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/9f299f5e-6a0c-4fe7-b22c-7367a30735f9.jpeg)

### アルファチャネルの作成

このステップはオプションです。白黒画像をアルファチャネル付きのマスクに変換して、画像編集APIで使用したい場合に行います。

```py
# 1. 白黒マスクをグレースケール画像として読み込む
mask = Image.open(img_path_mask).convert("L")

# 2. アルファチャンネルのスペースを確保するためにRGBAに変換する
mask_rgba = mask.convert("RGBA")

# 3. マスク自体を使用してアルファチャンネルを埋める
mask_rgba.putalpha(mask)

# 4. マスクをバイトに変換する
buf = BytesIO()
mask_rgba.save(buf, format="PNG")
mask_bytes = buf.getvalue()
```

```py
# 結果のファイルを保存する
img_path_mask_alpha = "imgs/mask_alpha.png"
with open(img_path_mask_alpha, "wb") as f:
    f.write(mask_bytes)
```
![mask_alpha.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/be8bcda4-5505-4dff-b8c4-cdb27d878eb8.png)

### マスクによる編集

マスクを使用する場合でも、マスクされた領域だけでなく、結果として得られる画像全体を説明するプロンプトが必要です。

```py
prompt_mask_edit = "奇妙なキャラクターが、たくさんの星や惑星があるカラフルな銀河の背景にいる。"
mask = open(img_path_mask_alpha, "rb")
```

```py
result_mask_edit = client.images.edit(
    model="gpt-image-1",         
    prompt=prompt_mask_edit,
    image=img_input,
    mask=mask,
    size="1024x1024"
)
```

```py
# 結果を表示

img_path_mask_edit = "imgs/mask_edit.png"

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

image = Image.open(BytesIO(image_bytes))
image = image.resize((300, 300), Image.LANCZOS)
image.save(img_path_mask_edit, format="JPEG", quality=80, optimize=True)
    
display(IPImage(img_path_mask_edit))
```

![download (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/bdfd98c6-82d9-47c0-980e-b01d6d586c15.png)

## まとめ

このクックブックでは、新しい画像生成モデルであるGPT Imageを使用して、ゼロから新しい画像を生成したり、参照画像を使用したりする方法を見てきました。また、入力画像に適用するためのアルファチャネル付きマスクの作成方法についても説明しました。これにより、画像編集をさらにガイドすることができます。

これを出発点として他のユースケースを探求してみてください。インスピレーションが必要な場合は、ドキュメントの[画像ギャラリー](https://platform.openai.com/docs/guides/image-generation?image-generation-model=gpt-image-1&gallery=open#generate-images)をチェックしてください。

楽しい構築を！

# 振り返り

おそらく現行のChatGPTでも背後ではこのような仕組みが動いているんだろうなと思いながら動かしてみました。画像というアウトプットはわかりやすくて楽しいです。そして、APIで画像生成モデルが呼び出せることで、バッチ処理や自動化も可能となります。

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)