awacke1 commited on
Commit
3f97e41
·
verified ·
1 Parent(s): 0afc5b2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -114
app.py CHANGED
@@ -1,8 +1,3 @@
1
- # With torch.nn as nn, we build the brain,
2
- # Gradio as gr, makes demos reign.
3
- # PIL's Image, Filter, Ops, and Chops,
4
- # transforms from torchvision, style never stops!
5
- ### 🖥️ New and Improved Application Code
6
  import numpy as np
7
  import torch
8
  import torch.nn as nn
@@ -10,17 +5,12 @@ import gradio as gr
10
  from PIL import Image, ImageFilter, ImageOps, ImageChops
11
  import torchvision.transforms as transforms
12
  import os
13
- import random
14
  import pathlib
15
 
16
  # --- ⚙️ Configuration ---
17
- # Create a directory to save output images
18
  output_dir = "outputs"
19
  os.makedirs(output_dir, exist_ok=True)
20
 
21
- # Define allowed image extensions for the file explorer
22
- IMAGE_EXTENSIONS = [".png", ".jpg", ".jpeg", ".bmp", ".gif", ".tiff"]
23
-
24
  # --- 🎨 Filters ---
25
  FILTERS = {
26
  "Standard": "📄", "Invert": "⚫⚪", "Blur": "🌫️", "Sharpen": "🔪", "Contour": "🗺️",
@@ -115,13 +105,11 @@ def apply_filter(line_img, filter_name, original_img):
115
  return Image.fromarray(noisy_array)
116
  return line_img
117
 
118
- # --- 🖼️ Main Processing Function (Updated) ---
119
- def process_image(input_img_path, line_style, filter_choice, gallery_state):
120
  if not model1 or not model2:
121
  raise gr.Error("Models are not loaded. Please check for 'model.pth' and 'model2.pth'.")
122
- if not input_img_path:
123
- raise gr.Error("Please select an image from the file explorer first.")
124
-
125
  filter_name = filter_choice.split(" ", 1)[1]
126
  original_img = Image.open(input_img_path).convert('RGB')
127
 
@@ -140,112 +128,50 @@ def process_image(input_img_path, line_style, filter_choice, gallery_state):
140
 
141
  final_image = apply_filter(line_drawing_full_res, filter_name, original_img)
142
 
143
- # --- 💾 Save the output and update gallery state ---
144
  base_name = pathlib.Path(input_img_path).stem
145
  output_filename = f"{base_name}_{filter_name}.png"
146
  output_filepath = os.path.join(output_dir, output_filename)
147
  final_image.save(output_filepath)
148
 
149
- # Add new image path to the beginning of the list
150
- gallery_state.insert(0, output_filepath)
151
-
152
- # Return the single latest image for the main output and the updated list for the gallery
153
- return final_image, gallery_state
154
 
155
  # --- 🚀 Gradio UI Setup ---
156
  title = "🖌️ Image to Line Art with Creative Filters"
157
- description = "1. Browse and select an image using the file explorer. 2. Choose a line style. 3. Pick a filter. Your results will be saved to the 'outputs' folder and appear in the gallery below."
158
-
159
- # --- Dynamic Examples Generation ---
160
- def generate_examples():
161
- example_images = [f"{i:02d}.jpeg" for i in range(1, 11)]
162
- # Filter for only existing example images
163
- valid_example_images = [img for img in example_images if os.path.exists(img)]
164
-
165
- if not valid_example_images:
166
- print("⚠️ Warning: No example images ('01.jpeg' through '10.jpeg') found. Examples will be empty.")
167
- return []
168
-
169
- examples = []
170
- for name, emoji in FILTERS.items():
171
- filter_choice = f"{emoji} {name}"
172
- random_image = random.choice(valid_example_images)
173
- line_style = random.choice(['Simple Lines', 'Complex Lines'])
174
- examples.append([random_image, line_style, filter_choice])
175
- # Shuffle to make the order random on each load
176
- random.shuffle(examples)
177
- return examples
178
-
179
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
180
- gr.Markdown(f"<h1 style='text-align: center;'>{title}</h1>")
181
- gr.Markdown(description)
182
-
183
- # Stores the list of gallery image paths
184
- gallery_state = gr.State(value=[])
185
-
186
- with gr.Row():
187
- with gr.Column(scale=1):
188
- gr.Markdown("### 1. Select an Image")
189
- #
190
- # ===== THIS IS THE CORRECTED LINE =====
191
- # The 'root' argument has been removed to support older Gradio versions
192
- #
193
- input_image_path = gr.FileExplorer(
194
- glob=f"**/*[{''.join(ext[1:] for ext in IMAGE_EXTENSIONS)}]",
195
- label="Browse Your Images",
196
- height=400
197
- )
198
- gr.Markdown("### 2. Choose a Line Style")
199
- line_style_radio = gr.Radio(
200
- ['Complex Lines', 'Simple Lines'],
201
- label="Line Style",
202
- value='Simple Lines'
203
- )
204
-
205
- with gr.Column(scale=3):
206
- gr.Markdown("### 3. Pick a Filter")
207
- filter_buttons = [gr.Button(value=f"{emoji} {name}") for name, emoji in FILTERS.items()]
208
-
209
- # Hidden radio to store the selected button's value
210
- selected_filter = gr.Radio(
211
- [b.value for b in filter_buttons],
212
- label="Selected Filter",
213
- visible=False,
214
- value=filter_buttons[0].value
215
- )
216
-
217
- gr.Markdown("### 4. Result")
218
- main_output_image = gr.Image(type="pil", label="Latest Result")
219
-
220
- with gr.Row():
221
- gr.Markdown("---")
222
-
223
- with gr.Row():
224
- # --- Dynamic Examples ---
225
- gr.Examples(
226
- examples=generate_examples(),
227
- inputs=[input_image_path, line_style_radio, selected_filter],
228
- label="✨ Click an Example to Start",
229
- examples_per_page=10
230
- )
231
-
232
- with gr.Row():
233
- gr.Markdown("## 🖼️ Result Gallery (Saved in 'outputs' folder)")
234
- gallery_output = gr.Gallery(label="Your Generated Images", height=600, columns=5)
235
-
236
- # --- Event Handling ---
237
- def handle_filter_click(btn_value, current_path, style, state):
238
- # When a filter button is clicked, it triggers the main processing function
239
- new_main_img, new_state = process_image(current_path, style, btn_value, state)
240
- # Update the hidden radio, the main image, and the gallery
241
- return btn_value, new_main_img, new_state
242
-
243
- for btn in filter_buttons:
244
- btn.click(
245
- fn=handle_filter_click,
246
- inputs=[btn, input_image_path, line_style_radio, gallery_state],
247
- outputs=[selected_filter, main_output_image, gallery_state]
248
- )
249
 
250
  if __name__ == "__main__":
251
- demo.launch()
 
 
 
 
 
 
1
  import numpy as np
2
  import torch
3
  import torch.nn as nn
 
5
  from PIL import Image, ImageFilter, ImageOps, ImageChops
6
  import torchvision.transforms as transforms
7
  import os
 
8
  import pathlib
9
 
10
  # --- ⚙️ Configuration ---
 
11
  output_dir = "outputs"
12
  os.makedirs(output_dir, exist_ok=True)
13
 
 
 
 
14
  # --- 🎨 Filters ---
15
  FILTERS = {
16
  "Standard": "📄", "Invert": "⚫⚪", "Blur": "🌫️", "Sharpen": "🔪", "Contour": "🗺️",
 
105
  return Image.fromarray(noisy_array)
106
  return line_img
107
 
108
+ # --- 🖼️ Main Processing Function ---
109
+ def predict(input_img_path, line_style, filter_choice):
110
  if not model1 or not model2:
111
  raise gr.Error("Models are not loaded. Please check for 'model.pth' and 'model2.pth'.")
112
+
 
 
113
  filter_name = filter_choice.split(" ", 1)[1]
114
  original_img = Image.open(input_img_path).convert('RGB')
115
 
 
128
 
129
  final_image = apply_filter(line_drawing_full_res, filter_name, original_img)
130
 
131
+ # --- 💾 Save the output image ---
132
  base_name = pathlib.Path(input_img_path).stem
133
  output_filename = f"{base_name}_{filter_name}.png"
134
  output_filepath = os.path.join(output_dir, output_filename)
135
  final_image.save(output_filepath)
136
 
137
+ return final_image
 
 
 
 
138
 
139
  # --- 🚀 Gradio UI Setup ---
140
  title = "🖌️ Image to Line Art with Creative Filters"
141
+ description = "Upload an image, choose a line style (Complex or Simple), and select a filter from the dropdown to transform your picture. Results are saved in the 'outputs' folder."
142
+
143
+ filter_choices = [f"{emoji} {name}" for name, emoji in FILTERS.items()]
144
+
145
+ # --- New Curated Examples Section ---
146
+ examples = []
147
+ example_images = [f"{i:02d}.jpeg" for i in range(1, 11)]
148
+ # A selection of 6 interesting filters to demonstrate
149
+ demo_filters = ["🗺️ Contour", "🔵⚫ BlueOnBlack", "✖️ Multiply", "🏞️ Emboss", "🔪 Sharpen", "❄️ Noise"]
150
+
151
+ # Create one example for each of the 10 image files, cycling through the demo filters
152
+ for i, img_file in enumerate(example_images):
153
+ if os.path.exists(img_file):
154
+ # Use modulo to cycle through the 6 demo filters for the 10 images
155
+ chosen_filter = demo_filters[i % len(demo_filters)]
156
+ examples.append([img_file, 'Simple Lines', chosen_filter])
157
+
158
+ if not examples:
159
+ print("⚠️ Warning: No example images ('01.jpeg' to '10.jpeg') found. Examples will be empty.")
160
+
161
+ # Reverted to the simpler and more stable gr.Interface
162
+ iface = gr.Interface(
163
+ fn=predict,
164
+ inputs=[
165
+ gr.Image(type='filepath', label="Upload Image"),
166
+ gr.Radio(['Complex Lines', 'Simple Lines'], label='Line Style', value='Simple Lines'),
167
+ gr.Dropdown(filter_choices, label="Filter", value=filter_choices[0])
168
+ ],
169
+ outputs=gr.Image(type="pil", label="Filtered Line Art"),
170
+ title=title,
171
+ description=description,
172
+ examples=examples,
173
+ allow_flagging='never'
174
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
 
176
  if __name__ == "__main__":
177
+ iface.launch()