Zack3D commited on
Commit
55375ee
·
verified ·
1 Parent(s): 9826e36

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +33 -9
app.py CHANGED
@@ -1,6 +1,5 @@
1
- # app.py
2
  """
3
- Gradio Space: GPT‑Image‑1 – BYOT playground
4
  Generate · Edit (paint mask!) · Variations
5
  ==========================================
6
  Adds an **in‑browser paint tool** for the edit / inpaint workflow so users can
@@ -10,7 +9,7 @@ draw the mask directly instead of uploading one.
10
  * Upload an image.
11
  * Use the *Mask* canvas to **paint the areas you’d like changed** (white =
12
  editable, black = keep).
13
- Gradio’s built‑in *sketch* tool captures your brush strokes.
14
  * The painted mask is converted to a 1‑channel PNG and sent to the
15
  `images.edit()` endpoint.
16
 
@@ -22,7 +21,7 @@ from __future__ import annotations
22
 
23
  import io
24
  import os
25
- from typing import List, Optional
26
 
27
  import gradio as gr
28
  import numpy as np
@@ -105,10 +104,33 @@ def _bytes_from_numpy(arr: np.ndarray) -> bytes:
105
  return out.getvalue()
106
 
107
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  def edit_image(
109
  api_key: str,
110
  image_numpy: np.ndarray,
111
- mask_numpy: Optional[np.ndarray],
112
  prompt: str,
113
  n: int,
114
  size: str,
@@ -122,11 +144,13 @@ def edit_image(
122
  img_bytes = _bytes_from_numpy(image_numpy)
123
 
124
  mask_bytes: Optional[bytes] = None
 
 
125
  if mask_numpy is not None:
126
- # Convert painted area (alpha > 0) to white, else black; 1‑channel.
127
- if mask_numpy.shape[-1] == 4: # RGBA from gr.Image sketch
128
  alpha = mask_numpy[:, :, 3]
129
- else: # RGB
130
  alpha = np.any(mask_numpy != 0, axis=-1).astype(np.uint8) * 255
131
  bw = np.stack([alpha] * 3, axis=-1) # 3‑channel white/black
132
  mask_bytes = _bytes_from_numpy(bw)
@@ -206,7 +230,7 @@ def build_ui():
206
  # ----- Edit Tab ----- #
207
  with gr.TabItem("Edit / Inpaint"):
208
  img_edit = gr.Image(label="Image", type="numpy")
209
- mask_canvas = gr.Image(label="Mask – paint white where the image should change", type="numpy", tool="sketch")
210
  prompt_edit = gr.Textbox(label="Edit prompt", lines=2, placeholder="Replace the sky with a starry night")
211
  btn_edit = gr.Button("Edit 🖌️")
212
  gallery_edit = gr.Gallery(columns=2, height="auto")
 
 
1
  """
2
+ Gradio Space: GPT‑Image‑1 – BYOT playground
3
  Generate · Edit (paint mask!) · Variations
4
  ==========================================
5
  Adds an **in‑browser paint tool** for the edit / inpaint workflow so users can
 
9
  * Upload an image.
10
  * Use the *Mask* canvas to **paint the areas you’d like changed** (white =
11
  editable, black = keep).
12
+ The new `gr.ImageMask` component captures your brush strokes.
13
  * The painted mask is converted to a 1‑channel PNG and sent to the
14
  `images.edit()` endpoint.
15
 
 
21
 
22
  import io
23
  import os
24
+ from typing import List, Optional, Union, Dict, Any
25
 
26
  import gradio as gr
27
  import numpy as np
 
104
  return out.getvalue()
105
 
106
 
107
+ def _extract_mask_array(mask_value: Union[np.ndarray, Dict[str, Any], None]) -> Optional[np.ndarray]:
108
+ """Handle ImageMask / ImageEditor return formats and extract a numpy mask array."""
109
+ if mask_value is None:
110
+ return None
111
+
112
+ # If we already have a numpy array (ImageMask with type="numpy")
113
+ if isinstance(mask_value, np.ndarray):
114
+ return mask_value
115
+
116
+ # If it's an EditorValue dict coming from ImageEditor/ImageMask with type="numpy"
117
+ if isinstance(mask_value, dict):
118
+ # Prefer the composite (all layers merged) if present
119
+ comp = mask_value.get("composite")
120
+ if comp is not None:
121
+ return np.asarray(comp)
122
+ # Fallback to the topmost layer
123
+ layers = mask_value.get("layers")
124
+ if layers:
125
+ return np.asarray(layers[-1])
126
+ # Unknown format – ignore
127
+ return None
128
+
129
+
130
  def edit_image(
131
  api_key: str,
132
  image_numpy: np.ndarray,
133
+ mask_value: Optional[Union[np.ndarray, Dict[str, Any]]],
134
  prompt: str,
135
  n: int,
136
  size: str,
 
144
  img_bytes = _bytes_from_numpy(image_numpy)
145
 
146
  mask_bytes: Optional[bytes] = None
147
+ mask_numpy = _extract_mask_array(mask_value)
148
+
149
  if mask_numpy is not None:
150
+ # Convert painted area (any non‑zero pixel) to white, else black; 1‑channel.
151
+ if mask_numpy.shape[-1] == 4: # RGBA (has alpha channel)
152
  alpha = mask_numpy[:, :, 3]
153
+ else: # RGB or grayscale
154
  alpha = np.any(mask_numpy != 0, axis=-1).astype(np.uint8) * 255
155
  bw = np.stack([alpha] * 3, axis=-1) # 3‑channel white/black
156
  mask_bytes = _bytes_from_numpy(bw)
 
230
  # ----- Edit Tab ----- #
231
  with gr.TabItem("Edit / Inpaint"):
232
  img_edit = gr.Image(label="Image", type="numpy")
233
+ mask_canvas = gr.ImageMask(label="Mask – paint white where the image should change", type="numpy")
234
  prompt_edit = gr.Textbox(label="Edit prompt", lines=2, placeholder="Replace the sky with a starry night")
235
  btn_edit = gr.Button("Edit 🖌️")
236
  gallery_edit = gr.Gallery(columns=2, height="auto")