· last year · Dec 06, 2023, 07:20 PM
1# Tutorial: https://www.youtube.com/watch?v=OatbzMJIfJM
2# pip install requests Pillow openai
3import tkinter as tk
4from tkinter import filedialog, ttk, messagebox, Canvas, Scrollbar
5from openai import OpenAI
6import threading
7import requests
8from PIL import Image, ImageTk
9import io
10import os
11import uuid
12
13# Save the API key securely
14def save_api_key():
15 with open('api_key.txt', 'w') as file:
16 file.write(api_key_entry.get())
17
18# Load the API key securely
19def load_api_key():
20 try:
21 with open('api_key.txt', 'r') as file:
22 api_key_entry.insert(0, file.read())
23 except FileNotFoundError:
24 messagebox.showerror("Error", "API Key file not found.")
25
26# Function to generate and display image(s)
27def generate_image_thread():
28 threading.Thread(target=generate_image).start()
29
30def generate_image():
31 clear_image_grid() # Added line to clear the image grid
32 status_label.config(text="Running")
33 client = OpenAI(api_key=api_key_entry.get())
34 prompt = prompt_entry.get("1.0", tk.END).strip()
35 size = size_var.get()
36 quality = quality_var.get()
37 num_images = int(num_images_var.get())
38
39 progress_bar['maximum'] = num_images
40 progress_bar['value'] = 0
41
42 try:
43 image_counter = 0
44 for _ in range(num_images):
45 response = client.images.generate(
46 model="dall-e-3",
47 prompt=prompt,
48 size=size,
49 quality=quality,
50 n=1,
51 )
52 img_url = response.data[0].url
53 img_response = requests.get(img_url)
54 img = Image.open(io.BytesIO(img_response.content))
55
56 display_img = img.copy()
57 display_img.thumbnail((400, 400)) # Resize for display
58 tk_img = ImageTk.PhotoImage(display_img)
59
60 image_label = tk.Label(image_frame, image=tk_img)
61 image_label.image = tk_img
62 image_label.grid(row=0, column=image_counter, padx=5, pady=5)
63 image_counter += 1
64
65 filename = f'{uuid.uuid4()}.png'
66 img.save(os.path.join(save_folder.get(), filename))
67
68 progress_bar['value'] += 1
69 root.update_idletasks()
70
71 except Exception as e:
72 messagebox.showerror("Error", f"An error occurred: {e}")
73
74 status_label.config(text="Idle")
75
76# Function to select save folder
77def select_save_folder():
78 folder_selected = filedialog.askdirectory()
79 save_folder.set(folder_selected if folder_selected else save_folder.get())
80
81# Function to clear image grid
82def clear_image_grid():
83 for widget in image_frame.winfo_children():
84 widget.destroy()
85
86# Custom style improvements
87def apply_custom_style(root):
88 style = ttk.Style(root)
89 style.theme_use('clam')
90
91 # Customizing general widget styles
92 style.configure('TLabel', background='#333333', foreground='#DDDDDD', font=('Arial', 14, 'bold'))
93 style.configure('TEntry', fieldbackground='#555555', foreground='#EEEEEE', font=('Arial', 14, 'bold'))
94 style.configure('TButton', background='#444444', foreground='#FFFFFF', font=('Arial', 14, 'bold'), borderwidth=1)
95 style.configure('TCheckbutton', background='#333333', foreground='#FFFFFF', font=('Arial', 14, 'bold'))
96 style.configure('TFrame', background='#333333')
97 style.configure('Horizontal.TProgressbar', background='#5AA33F', troughcolor='#333333')
98 style.configure('TCombobox', font=('Arial', 12)) # Adjusting font size for dropdown menus
99
100 # Customizing specific widget styles
101 style.map('TButton', background=[('active', '#555555')], foreground=[('active', '#FFFFFF')])
102 return style
103
104# Horizontal Scrollable Image Frame
105def create_scrollable_image_frame(root):
106 canvas = Canvas(root, bg="#333333")
107 scrollbar = Scrollbar(root, orient="horizontal", command=canvas.xview)
108 scrollable_frame = ttk.Frame(canvas)
109
110 scrollable_frame.bind(
111 "<Configure>",
112 lambda e: canvas.configure(
113 scrollregion=canvas.bbox("all")
114 )
115 )
116
117 canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
118 canvas.configure(xscrollcommand=scrollbar.set)
119
120 canvas.pack(side="top", fill="both", expand=True)
121 scrollbar.pack(side="bottom", fill="x")
122
123 return scrollable_frame
124
125# Create the main window
126root = tk.Tk()
127root.title("dall-e-desktop-ui")
128root.geometry('800x800') # Set initial size
129root.config(bg="#333333")
130
131apply_custom_style(root) # Apply custom styles
132
133# Variables for UI elements
134size_var = tk.StringVar(value="1024x1024")
135quality_var = tk.StringVar(value="standard")
136num_images_var = tk.StringVar(value="1")
137save_folder = tk.StringVar(value=os.path.expanduser("~"))
138
139# API Key UI
140api_key_label = ttk.Label(root, text="API Key:")
141api_key_label.pack(pady=(10, 0))
142api_key_entry = ttk.Entry(root)
143api_key_entry.pack(padx=10, pady=5)
144save_api_button = ttk.Button(root, text="Save API Key", command=save_api_key)
145save_api_button.pack(pady=5)
146
147# Dropdowns for Size, Quality, and Number of Images
148settings_frame = ttk.Frame(root)
149settings_frame.pack(padx=10, pady=10, fill='x')
150ttk.Label(settings_frame, text="Image Size:").pack(side='left')
151ttk.Combobox(settings_frame, textvariable=size_var, values=["1024x1024", "1024x1792", "1792x1024"]).pack(side='left')
152ttk.Label(settings_frame, text="Image Quality:").pack(side='left')
153ttk.Combobox(settings_frame, textvariable=quality_var, values=["standard", "hd"]).pack(side='left')
154ttk.Label(settings_frame, text="Number of Images:").pack(side='left')
155ttk.Combobox(settings_frame, textvariable=num_images_var, values=[str(x) for x in range(1, 11)]).pack(side='left')
156
157# Prompt Text Area
158prompt_label = ttk.Label(root, text="Prompt:")
159prompt_label.pack(pady=(10, 0))
160prompt_entry = tk.Text(root, height=4)
161prompt_entry.pack(fill='both', expand=True, padx=10, pady=5)
162
163# Save Folder UI
164save_folder_frame = ttk.Frame(root)
165save_folder_frame.pack(padx=10, pady=10, fill='x')
166ttk.Label(save_folder_frame, text="Save Images to:").pack(side='left')
167save_folder_entry = ttk.Entry(save_folder_frame, textvariable=save_folder)
168save_folder_entry.pack(side='left', fill='x', expand=True)
169select_folder_button = ttk.Button(save_folder_frame, text="Select Folder", command=select_save_folder)
170select_folder_button.pack(side='left')
171
172# Generate Image Button and Progress Bar
173generate_button = ttk.Button(root, text="Generate Image", command=generate_image_thread)
174generate_button.pack(pady=5)
175progress_bar = ttk.Progressbar(root, orient='horizontal', length=200, mode='determinate', style='Horizontal.TProgressbar')
176progress_bar.pack(pady=(5, 10))
177
178# Image Display Frame
179image_frame = create_scrollable_image_frame(root)
180
181# Status Label
182status_label = ttk.Label(root, text="Idle")
183status_label.pack(pady=(5, 10))
184
185# Load the API key if it exists
186load_api_key()
187
188root.mainloop()