Shafi99 commited on
Commit
4668ada
·
verified ·
1 Parent(s): 60224ac

Return a fast preview plus the lossless PNG, and isolate per-request files

Browse files
Files changed (1) hide show
  1. app.py +25 -7
app.py CHANGED
@@ -11,6 +11,7 @@ decision here, not only a memory one.
11
  """
12
  import os
13
  import re
 
14
  import time
15
 
16
  import gradio as gr
@@ -168,13 +169,19 @@ def _check(image):
168
  return image.convert("RGB")
169
 
170
 
 
 
 
 
 
 
171
  def restore(image):
172
  """The built-in page: both halves for the slider, plus a lossless download."""
173
  image = _check(image)
174
  t0 = time.time()
175
  result = _run(image)
176
  t_inf = time.time() - t0
177
- path = os.path.join("/tmp" if os.path.isdir("/tmp") else ".", "restored.png")
178
  result.save(path, "PNG", optimize=False) # lossless, nothing added after the model
179
  n = _tile_count(*image.size)
180
  return (image, result), path, "%d by %d px, %d tiles, %.1f s on the GPU (%.2f s per tile)" % (
@@ -182,12 +189,21 @@ def restore(image):
182
 
183
 
184
  def restore_api(image):
185
- """Lean endpoint for a standalone front end: the restored photo only.
186
 
187
- The caller already holds the original, so echoing it back would double the
188
- download for nothing. Returned as PNG, so nothing is re-compressed.
 
 
 
189
  """
190
- return _run(_check(image))
 
 
 
 
 
 
191
 
192
 
193
  CSS = ".contain{max-width:1100px!important}"
@@ -220,9 +236,11 @@ with gr.Blocks(title="iPhoneBlur Restore") as demo:
220
  # the caller can fetch; gr.api returned the repr of the image object instead.
221
  with gr.Row(visible=False):
222
  api_in = gr.Image(type="pil", image_mode="RGB", format="png")
223
- api_out = gr.Image(type="pil", format="png")
 
224
  api_btn = gr.Button("api")
225
- api_btn.click(restore_api, inputs=api_in, outputs=api_out, api_name="restore_image")
 
226
 
227
  if __name__ == "__main__":
228
  demo.queue(max_size=20).launch(css=CSS, theme=gr.themes.Soft(), show_error=True)
 
11
  """
12
  import os
13
  import re
14
+ import tempfile
15
  import time
16
 
17
  import gradio as gr
 
169
  return image.convert("RGB")
170
 
171
 
172
+ def _outdir():
173
+ """A fresh directory per request. A fixed filename would let two visitors
174
+ overwrite each other's result."""
175
+ return tempfile.mkdtemp(prefix="restore_")
176
+
177
+
178
  def restore(image):
179
  """The built-in page: both halves for the slider, plus a lossless download."""
180
  image = _check(image)
181
  t0 = time.time()
182
  result = _run(image)
183
  t_inf = time.time() - t0
184
+ path = os.path.join(_outdir(), "restored.png")
185
  result.save(path, "PNG", optimize=False) # lossless, nothing added after the model
186
  n = _tile_count(*image.size)
187
  return (image, result), path, "%d by %d px, %d tiles, %.1f s on the GPU (%.2f s per tile)" % (
 
189
 
190
 
191
  def restore_api(image):
192
+ """Lean endpoint for a standalone front end.
193
 
194
+ Returns two files rather than one: a small preview to show straight away, and the
195
+ lossless PNG. Both come back as URLs, so the browser only pulls the big one if the
196
+ visitor actually clicks download. Measured on a 0.9 Mbps line, the PNG alone took
197
+ 23.6 s to transfer while the GPU work took 4.2 s, so the preview is what makes this
198
+ usable on a slow connection. Nothing is re-compressed in the file people keep.
199
  """
200
+ result = _run(_check(image))
201
+ d = _outdir()
202
+ png = os.path.join(d, "restored.png")
203
+ preview = os.path.join(d, "preview.webp")
204
+ result.save(png, "PNG", optimize=False)
205
+ result.save(preview, "WEBP", quality=92, method=4)
206
+ return preview, png
207
 
208
 
209
  CSS = ".contain{max-width:1100px!important}"
 
236
  # the caller can fetch; gr.api returned the repr of the image object instead.
237
  with gr.Row(visible=False):
238
  api_in = gr.Image(type="pil", image_mode="RGB", format="png")
239
+ api_preview = gr.File() # gr.File passes bytes through untouched,
240
+ api_full = gr.File() # gr.Image would re-encode and break "lossless"
241
  api_btn = gr.Button("api")
242
+ api_btn.click(restore_api, inputs=api_in, outputs=[api_preview, api_full],
243
+ api_name="restore_image")
244
 
245
  if __name__ == "__main__":
246
  demo.queue(max_size=20).launch(css=CSS, theme=gr.themes.Soft(), show_error=True)