東京都府中市、九段下のWEB制作会社Maromaroのブログです

2024.06.24

Sasaki

OpenAIの画像生成AIを利用してみた

こんにちは!佐々木です。

OpenAIのAPIを用いて、生成AIを利用し画像を作成してみたいと思います。(なんかややこしい)

 

ざっくり手順

 

  • OpenAIのAPIにサインアップ
    https://platform.openai.com/login?launch
    ※ChatGPTと入口が違うので注意
  • ログイン後APIを選択
  • 各々のAPIを選択
  • 使い方に沿って利用

となります。

下地の準備

今回はpythonを用いて実行してみます。
https://platform.openai.com/docs/quickstart?context=python

上記にアクセスをして、「Step 1: Setting up Python」から試してみる。

pythonがもうはいっていれば「Install the OpenAI Python library」から試せばOK

pip install --upgrade openai

次はOpenAPIのキーを設定する「Step 2: Set up your API key」を参照

export OPENAI_API_KEY='your-api-key-here'

your-api-key-hereとなっているところにAPIキーをいれる。
でコマンド実行する。
※APIキーはプロジェクトの左メニュー「API keys」から作成可能

これで事前準備は完了

今回は画像生成AIを利用してみる

https://platform.openai.com/docs/guides/images/usage

この方法に従ってやってみる

まずはそのままコード実行します。
生成のプロンプトは「a white siamese cat」
白い猫ちゃんが生成される感じですね。

▼コード

from openai import OpenAI
client = OpenAI()
response = client.images.generate(
  model="dall-e-3",
  prompt="a white siamese cat",
  size="1024x1024",
  quality="standard",
  n=1,
)
image_url = response.data[0].url

print(response.data)

適当に「openaitest.py」などとしてファイルに保存。

print(response.data)だけ追加しました。

python ./openaitest.py

などと実行してみると、結果が出てきたと思います。

表示されたURLを抜き出してブラウザなどにいれてみると、下記のような画像が生成されました。
可愛いですね〜

※生成されたURLは60分有効のようです。
 生成時のオプションにresponse_formatをb64_jsonとすると「base64」形式で返却されます。

 

ひとまずサンプルは動きました!

 

画像のたりない部分を補うインペインティング

たとえば1000px x 1000pxの元画像を1400px x 1000pxなどにする際に
不足部分を補足するようなコード生成を考えます。

例えば下記のようなサンプル熊を用いて生成してみます。

生成に利用できる画像はPNG形式のみです。

▼コード

from openai import OpenAI
client = OpenAI()
from PIL import Image, ImageDraw
import base64
import io

def expand_image(image_path, new_width, new_height):
image = Image.open(image_path)
original_width, original_height = image.size

# 新しい画像を作成し、中央に元の画像を貼り付ける
new_image = Image.new("RGB", (new_width, new_height), (255, 255, 255))
paste_x = (new_width - original_width) // 2
paste_y = (new_height - original_height) // 2
new_image.paste(image, (paste_x, paste_y))

# マスク画像を生成(透過部分に画像が生成される)
mask = Image.new("RGBA", (new_width, new_height), 0)
mask.paste(image, (paste_x, paste_y))


return new_image, mask

def save_images(image, mask, image_path, mask_path):
image.save(image_path)
mask.save(mask_path)

def openai_image_inpainting(image_path, mask_path, output_path):
with open(image_path, "rb") as image_file, open(mask_path, "rb") as mask_file:
image_data = image_file.read()
mask_data = mask_file.read()

response = client.images.edit(
response_format="b64_json",
prompt="Fill the missing parts of the image",
n=1,
size= "1024x1024",
image=image_data,
mask=mask_data
)
#print(response.data)
# 生成された画像を保存
image_bytes = base64.b64decode(response.data[0].b64_json)
with open(output_path, "wb") as f:
f.write(image_bytes)

def resize_image(image_path, output_path, new_size):
image = Image.open(image_path)
resized_image = image.resize(new_size, Image.LANCZOS)
resized_image.save(output_path)


# 使用例
image_path = "test.png"
expanded_image_path = "expand_image.png" #拡張するべきところが増えている
mask_path = "mask.png"
output_path = "generated_image.png"
final_output_path = "final_output.png"
width = 1400
height = 1000

# 画像を拡張し、マスクを生成
new_image, mask = expand_image(image_path,width,height)
save_images(new_image, mask, expanded_image_path, mask_path)

# 画像を補完
openai_image_inpainting(expanded_image_path, mask_path, output_path)

# 補完された画像をリサイズ
resize_image(output_path, final_output_path, (width, height))

実行してみると下記のようになりました!!
若干左右に歪みがありますね・・・。

ちょっと画像が複雑なので、別のものであればまた結果が違うかもですね。(命令によっても変わるかも)

画像投稿時の自動延長などに使えるかも?
すでにPhotoshopでもできますが、自動化したい場合もありそうですよね。(CMSからの登録など)

※ただし注意点として、OpenAPI側での画像生成サイズがきまっているため、大きな画像にはむいていなそうです。

以上、佐々木でした!