見出し画像

Python tkinterを使ってOpenAIで画像を生成させるプログラム

Pythonという言語は以前から知っていたけど縁もやる気もなく今まで触らずにいましたがOpenAIとも親和性が高そうなのを知り今後に役立つだろうと考えて入門してみました。

入門して2日目に作ったプログラムなのでプロの方から見ると拙いものとなっていると思いますがこれから入門してみようという人に興味を持ってもらえたらなと思って公開しておりますのでご了承ください。

日本語でAIに生成して欲しい画像の指示文章を入力してボタンをクリックするだけでカレントディレクトリにダウンロードの上、画面上に4つの画像を表示します。あくまでもサンプルプログラムなので簡易な機能しか実装していません。画像の拡大表示や保存場所の変更などを自分で弄って拡張しては如何でしょうか。

OpenAIのライセンスの都合上1分以内に連続して生成するとエラーが出ます。金払えば解決するのだと思います。あと試用期間があって無料で使えるのは最初のうちだけだと思います。

他のプログラミング言語を習得していればそれ程難しくないのでプログラミング経験があってOpenAIに興味がある人はとりあえず体験してみてはいかがでしょうか。動作環境は下の方にあります。
OpenAIのユーザー登録は必須なのでどこかで調べてAPIキーを取得してください。
OpenAI APIの使い方は知人に教えてもらいましたが、知人曰く「ほとんどChatGPTで作らせたコード」だそうです。凄い時代ですね。

import tkinter as tk
from tkinter import messagebox
from PIL import Image, ImageTk
import openai
import base64

class Application(tk.Frame):
    NUMBER_OF_IMAGES = 4
    OPENAI_API_KEY = "あなたのAPIキーを入れてね"
    CANVAS_BASE_X = 22
    CANVAS_BASE_Y = 120
    CANVAS_EXT_X = 440
    CANVAS_EXT_Y = 536
    cans = {}

    def __init__(self,master = None):
        super().__init__(master)
        self.pack()

        master.geometry("860x960")
        master.title("OpenAiで画像生成しちゃうよん")
        openai.api_key = self.OPENAI_API_KEY
        self.create_controls()
    
    def create_canvases(self):
        i = 0
        while i < 4:
            can = tk.Canvas(self.master, bg="white", width=400, height=400)
            if i == 0: can.place(x=self.CANVAS_BASE_X, y=self.CANVAS_BASE_Y)
            elif i == 1: can.place(x=self.CANVAS_EXT_X, y=self.CANVAS_BASE_Y)
            elif i == 2: can.place(x=self.CANVAS_BASE_X, y=self.CANVAS_EXT_Y)
            else: can.place(x=self.CANVAS_EXT_X, y=self.CANVAS_EXT_Y)
            self.cans[i] = can
            i += 1

    def create_controls(self):
        tk.Label(text="生成呪文").place(x=20, y=20)
        self.tbKeyword = tk.Text(width=92, height=6)
        self.tbKeyword.place(x=90, y=22)
        btnA = tk.Button(self.master, text="生成しちゃうぞ!", command=self.btn_Click, width=12, height=5)
        btnA.place(x=750, y=18)
        self.create_canvases()
    
    def btn_Click(self):
        origin_wd = self.tbKeyword.get("1.0", "end")
        if (len(origin_wd) == 1): return
        image_wd = self.GenarateRequestWord(origin_wd)
        if (image_wd == None): return
        if (self.GenerateImages(image_wd) == None): return;
        self.showGeneratedImages()
    
    def showGeneratedImages(self):
        i = 0
        while i < 4:
            img = Image.open(f"{i}.png")
            img = img.resize((400, 400))
            self.cans[i].photo = ImageTk.PhotoImage(img)
            self.cans[i].create_image(0, 0, image=self.cans[i].photo, anchor=tk.NW)
            i += 1
        
    def GenerateImages(self, word):
        try:
            response = openai.Image.create(
                prompt = word,
                n=self.NUMBER_OF_IMAGES,
                size="1024x1024",
                response_format="b64_json",
            )

            for data, n in zip(response["data"], range(self.NUMBER_OF_IMAGES)):
                img_data = base64.b64decode(data["b64_json"])
                filename = f"./{n}.png"
                with open(filename, "wb") as f:
                    f.write(img_data)
            return True
        except openai.error.RateLimitError as e:
            messagebox.showerror("OpenAIエラー", f"OpenAI API request exceeded rate limit: {e}")
            return None

    def GenarateRequestWord(self, word):
        requestWord = "次の原文を前書きや挨拶など余分な出力なしで、画像生成AIに素晴らしい画像を出力させるための指示文章を英語で出力してください。原文「"
        requestWord = requestWord + word + "」"
        try:
            completion = openai.ChatCompletion.create(
                model="gpt-3.5-turbo", 
                messages=[{"role": "user", "content": requestWord}]
            )
            return completion.choices[0].message.content
        except openai.error.RateLimitError as e:
            messagebox.showerror("OpenAIエラー", f"OpenAI API request exceeded rate limit: {e}")
            return None     

def main():
    win = tk.Tk()
    app = Application(master=win)
    app.mainloop()

if __name__ == "__main__":
    main()

動作環境

Python 3.11.1
Pillow 9.5.0
openai 0.27.4

参考画像(スクリーンショット)

いいなと思ったら応援しよう!