Move image resizing to frontend
Browse files
app.py
CHANGED
@@ -66,20 +66,6 @@ def process_image(image):
|
|
66 |
|
67 |
return sorted_probs
|
68 |
|
69 |
-
def resize_image(image, max_size=512):
|
70 |
-
"""Resize image to have a maximum dimension of max_size while preserving aspect ratio"""
|
71 |
-
width, height = image.size
|
72 |
-
if width > height:
|
73 |
-
if width > max_size:
|
74 |
-
new_width = max_size
|
75 |
-
new_height = int(height * (max_size / width))
|
76 |
-
else:
|
77 |
-
if height > max_size:
|
78 |
-
new_height = max_size
|
79 |
-
new_width = int(width * (max_size / height))
|
80 |
-
else:
|
81 |
-
return image
|
82 |
-
return image.resize((new_width, new_height), Image.Resampling.LANCZOS)
|
83 |
|
84 |
class GameState:
|
85 |
def __init__(self):
|
@@ -91,10 +77,35 @@ class GameState:
|
|
91 |
self.is_game_active = False
|
92 |
self.last_results = None
|
93 |
self.waiting_for_input = True
|
94 |
-
self.original_image = None
|
95 |
|
96 |
def reset(self):
|
97 |
self.__init__()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
|
99 |
game_state = GameState()
|
100 |
|
@@ -146,29 +157,26 @@ def start_game():
|
|
146 |
game_state.game_images = load_images()
|
147 |
game_state.is_game_active = True
|
148 |
game_state.waiting_for_input = True
|
149 |
-
|
150 |
-
# Store original image and create resized version for display
|
151 |
-
game_state.original_image = Image.open(game_state.game_images[0])
|
152 |
-
display_image = resize_image(game_state.original_image)
|
153 |
|
154 |
return (
|
155 |
-
gr.update(value=
|
156 |
-
gr.update(visible=False),
|
157 |
-
gr.update(visible=True, interactive=True),
|
158 |
-
gr.update(visible=True, interactive=True),
|
159 |
create_score_html(),
|
160 |
-
gr.update(visible=False)
|
161 |
)
|
162 |
|
163 |
def submit_guess(user_guess):
|
164 |
if not game_state.is_game_active or not game_state.waiting_for_input:
|
165 |
return [gr.update()] * 6
|
166 |
-
|
167 |
-
model_prediction = process_image(game_state.original_image)
|
168 |
-
correct_answer = "Real" if "real_images" in game_state.game_images[game_state.current_round] else "Fake"
|
169 |
|
170 |
-
#
|
|
|
|
|
171 |
model_guess = "Real" if model_prediction['Authentic'] > PROB_THRESHOLD else "Fake"
|
|
|
172 |
|
173 |
# Update scores
|
174 |
if user_guess == correct_answer:
|
@@ -195,15 +203,13 @@ def submit_guess(user_guess):
|
|
195 |
gr.update(visible=False),
|
196 |
gr.update(visible=False),
|
197 |
create_score_html(),
|
198 |
-
gr.update(visible=True, value=
|
199 |
)
|
200 |
-
|
201 |
-
|
202 |
-
game_state.original_image = Image.open(game_state.game_images[game_state.current_round])
|
203 |
-
display_image = resize_image(game_state.original_image)
|
204 |
|
205 |
return (
|
206 |
-
gr.update(value=
|
207 |
gr.update(visible=False),
|
208 |
gr.update(visible=True, interactive=True),
|
209 |
gr.update(visible=True, interactive=True),
|
@@ -231,6 +237,11 @@ custom_css = """
|
|
231 |
.guess-button {
|
232 |
min-width: 120px;
|
233 |
}
|
|
|
|
|
|
|
|
|
|
|
234 |
"""
|
235 |
|
236 |
# Define Gradio interface
|
@@ -262,7 +273,8 @@ with gr.Blocks(css=custom_css) as iface:
|
|
262 |
type="pil",
|
263 |
label="Current Image",
|
264 |
interactive=False,
|
265 |
-
visible=False
|
|
|
266 |
)
|
267 |
with gr.Row(elem_id="guess-buttons"):
|
268 |
real_button = gr.Button(
|
|
|
66 |
|
67 |
return sorted_probs
|
68 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
class GameState:
|
71 |
def __init__(self):
|
|
|
77 |
self.is_game_active = False
|
78 |
self.last_results = None
|
79 |
self.waiting_for_input = True
|
|
|
80 |
|
81 |
def reset(self):
|
82 |
self.__init__()
|
83 |
+
|
84 |
+
def get_game_over_message(self):
|
85 |
+
if self.user_score > self.model_score:
|
86 |
+
return """
|
87 |
+
<div style='text-align: center; margin-top: 20px; font-size: 1.2em;'>
|
88 |
+
🎉 Congratulations! You won! 🎉<br>
|
89 |
+
You've outperformed SuSy in detecting AI-generated images.<br>
|
90 |
+
Click 'Start New Game' to play again.
|
91 |
+
</div>
|
92 |
+
"""
|
93 |
+
elif self.user_score < self.model_score:
|
94 |
+
return """
|
95 |
+
<div style='text-align: center; margin-top: 20px; font-size: 1.2em;'>
|
96 |
+
Better luck next time! SuSy won this round.<br>
|
97 |
+
Keep practicing to improve your detection skills.<br>
|
98 |
+
Click 'Start New Game' to try again.
|
99 |
+
</div>
|
100 |
+
"""
|
101 |
+
else:
|
102 |
+
return """
|
103 |
+
<div style='text-align: center; margin-top: 20px; font-size: 1.2em;'>
|
104 |
+
It's a tie! You matched SuSy's performance!<br>
|
105 |
+
You're getting good at this.<br>
|
106 |
+
Click 'Start New Game' to play again.
|
107 |
+
</div>
|
108 |
+
"""
|
109 |
|
110 |
game_state = GameState()
|
111 |
|
|
|
157 |
game_state.game_images = load_images()
|
158 |
game_state.is_game_active = True
|
159 |
game_state.waiting_for_input = True
|
160 |
+
current_image = Image.open(game_state.game_images[0])
|
|
|
|
|
|
|
161 |
|
162 |
return (
|
163 |
+
gr.update(value=current_image, visible=True),
|
164 |
+
gr.update(visible=False),
|
165 |
+
gr.update(visible=True, interactive=True),
|
166 |
+
gr.update(visible=True, interactive=True),
|
167 |
create_score_html(),
|
168 |
+
gr.update(visible=False)
|
169 |
)
|
170 |
|
171 |
def submit_guess(user_guess):
|
172 |
if not game_state.is_game_active or not game_state.waiting_for_input:
|
173 |
return [gr.update()] * 6
|
|
|
|
|
|
|
174 |
|
175 |
+
# Compute Model Guess
|
176 |
+
current_image = Image.open(game_state.game_images[game_state.current_round])
|
177 |
+
model_prediction = process_image(current_image)
|
178 |
model_guess = "Real" if model_prediction['Authentic'] > PROB_THRESHOLD else "Fake"
|
179 |
+
correct_answer = "Real" if "real_images" in game_state.game_images[game_state.current_round] else "Fake"
|
180 |
|
181 |
# Update scores
|
182 |
if user_guess == correct_answer:
|
|
|
203 |
gr.update(visible=False),
|
204 |
gr.update(visible=False),
|
205 |
create_score_html(),
|
206 |
+
gr.update(visible=True, value=game_state.get_game_over_message())
|
207 |
)
|
208 |
+
|
209 |
+
next_image = Image.open(game_state.game_images[game_state.current_round])
|
|
|
|
|
210 |
|
211 |
return (
|
212 |
+
gr.update(value=next_image, visible=True),
|
213 |
gr.update(visible=False),
|
214 |
gr.update(visible=True, interactive=True),
|
215 |
gr.update(visible=True, interactive=True),
|
|
|
237 |
.guess-button {
|
238 |
min-width: 120px;
|
239 |
}
|
240 |
+
.image-container img {
|
241 |
+
max-height: 768px !important;
|
242 |
+
width: auto !important;
|
243 |
+
object-fit: contain !important;
|
244 |
+
}
|
245 |
"""
|
246 |
|
247 |
# Define Gradio interface
|
|
|
273 |
type="pil",
|
274 |
label="Current Image",
|
275 |
interactive=False,
|
276 |
+
visible=False,
|
277 |
+
elem_classes=["image-container"]
|
278 |
)
|
279 |
with gr.Row(elem_id="guess-buttons"):
|
280 |
real_button = gr.Button(
|