yizhangliu commited on
Commit
34ad85b
1 Parent(s): 4d7b974

add js script to adapt to mobile devices

Browse files
Files changed (1) hide show
  1. app.py +29 -166
app.py CHANGED
@@ -4,7 +4,6 @@ import numpy as np
4
  import os,sys
5
  import torch
6
  import cv2
7
- import base64
8
 
9
  import io
10
  import multiprocessing
@@ -12,7 +11,8 @@ import random
12
  import time
13
  from loguru import logger
14
 
15
- from share_btn import community_icon_html, loading_icon_html, share_js
 
16
 
17
  from lama_cleaner.model_manager import ModelManager
18
  from lama_cleaner.schema import Config
@@ -99,11 +99,13 @@ model = None
99
  def model_process(image, mask, img_enhancer):
100
  global model,image_enhancer
101
 
 
102
  if mask.shape[0] == image.shape[1] and mask.shape[1] == image.shape[0] and mask.shape[0] != mask.shape[1]:
103
  # rotate image
104
- image = np.transpose(image[::-1, ...][:, ::-1], axes=(1, 0, 2))[::-1, ...]
105
-
106
- original_shape = image.shape
 
107
  interpolation = cv2.INTER_CUBIC
108
 
109
  size_limit = 1080
@@ -167,7 +169,7 @@ def model_process(image, mask, img_enhancer):
167
  log_info = f"image_enhancer_: {(time.time() - start) * 1000}ms, {res_np_img.shape} "
168
  logger.info(log_info)
169
 
170
- return image
171
 
172
  def resize_image(pil_image, new_width=400):
173
  width, height = pil_image.size
@@ -181,9 +183,9 @@ model = ModelManager(
181
  )
182
 
183
  image_type = 'pil' # filepath'
184
- def predict(input, img_enhancer):
185
  if input is None:
186
- return None
187
  if image_type == 'filepath':
188
  # input: {'image': '/tmp/tmp8mn9xw93.png', 'mask': '/tmp/tmpn5ars4te.png'}
189
  origin_image_bytes = open(input["image"], 'rb').read()
@@ -196,165 +198,12 @@ def predict(input, img_enhancer):
196
  mask_pil = input['mask']
197
  image = np.array(image_pil)
198
  mask = np.array(mask_pil.convert("L"))
199
- output = model_process(image, mask, img_enhancer)
200
- return output, [resize_image(image_pil, new_width=400), resize_image(output, new_width=400)], gr.update(visible=True)
201
-
202
- css = '''
203
- .container {max-width: 1150px; margin: auto;padding-top: 1.5rem}
204
- #begin-btn {color: blue; font-size:20px;}
205
- #work-container {min-width: min(160px, 100%) !important;flex-grow: 0 !important}
206
-
207
- #op-container{margin: 0 auto; text-align: center;width:fit-content;min-width: min(150px, 100%);flex-grow: 0; flex-wrap: nowrap;}
208
- #erase-btn-container{margin: 0 auto; text-align: center;width:150px;border-width:3px;border-color:#2c9748}
209
- #erase-btn {padding:0;}
210
- #enhancer-checkbox{width:520px}
211
- #enhancer-tip{width:450px}
212
- #enhancer-tip-div{text-align: left}
213
-
214
- #image_output{margin: 0 auto; text-align: center;width:640px}
215
-
216
- #download-container{margin: 0 auto; text-align: center;width:fit-content; min-width: min(150px, 100%);flex-grow: 0; flex-wrap: nowrap;}
217
-
218
- #download-btn-container{margin: 0 auto; text-align: center;width: 100px;border-width:1px;border-color:#2c9748}
219
- #download-btn {padding:0;}
220
-
221
- #share-container{margin: 0 auto; text-align: center;width:fit-content; min-width: min(150px, 100%);flex-grow: 0; flex-wrap: nowrap;}
222
-
223
- #image_upload .touch-none{display: flex}
224
- @keyframes spin {
225
- from {
226
- transform: rotate(0deg);
227
- }
228
- to {
229
- transform: rotate(360deg);
230
- }
231
- }
232
- #share-btn-container {
233
- display: flex; padding-left: 0.5rem !important; padding-right: 0.5rem !important; background-color: #000000; justify-content: center; align-items: center; border-radius: 9999px !important; width: 13rem;
234
- }
235
- #share-btn {
236
- all: initial; color: #ffffff;font-weight: 600; cursor:pointer; font-family: 'IBM Plex Sans', sans-serif; margin-left: 0.5rem !important; padding-top: 0.25rem !important; padding-bottom: 0.25rem !important;
237
- }
238
- #share-btn * {
239
- all: unset;
240
- }
241
- #share-btn-container div:nth-child(-n+2){
242
- width: auto !important;
243
- min-height: 0px !important;
244
- }
245
- #share-btn-container .wrap {
246
- display: none !important;
247
- }
248
- '''
249
- start_cleaner = """async() => {
250
- function isMobile() {
251
- try {
252
- document.createEvent("TouchEvent"); return true;
253
- } catch(e) {
254
- return false;
255
- }
256
- }
257
- var gradioEl = document.querySelector('body > gradio-app').shadowRoot;
258
- if (!gradioEl) {
259
- gradioEl = document.querySelector('body > gradio-app');
260
- }
261
- const group1 = gradioEl.querySelectorAll('#group_1')[0];
262
- const group2 = gradioEl.querySelectorAll('#group_2')[0];
263
- const image_upload = gradioEl.querySelectorAll('#image_upload')[0];
264
- const image_output = gradioEl.querySelectorAll('#image_output')[0];
265
- const image_output_container = gradioEl.querySelectorAll('#image-output-container')[0];
266
- const data_image = gradioEl.querySelectorAll('#image_upload [data-testid="image"]')[0];
267
- const data_image_div = gradioEl.querySelectorAll('#image_upload [data-testid="image"] > div')[0];
268
-
269
- image_output_container.setAttribute('style', 'width: 0px; height:0px; display:none;');
270
- if (isMobile()) {
271
- const group1_width = group1.offsetWidth;
272
-
273
- image_upload.setAttribute('style', 'width:' + (group1_width - 13*2) + 'px; min-height:none;');
274
- data_image.setAttribute('style', 'width: ' + (group1_width - 14*2) + 'px;min-height:none;');
275
- data_image_div.setAttribute('style', 'width: ' + (group1_width - 14*2) + 'px;min-height:none;');
276
- image_output.setAttribute('style', 'width: ' + (group1_width - 13*2) + 'px;min-height:none;');
277
-
278
- const enhancer = gradioEl.querySelectorAll('#enhancer-checkbox')[0];
279
- enhancer.style.display = "none";
280
-
281
- } else {
282
- max_height = 800;
283
-
284
- const container = gradioEl.querySelectorAll('.container')[0];
285
- container.setAttribute('style', 'max-width: 100%;');
286
-
287
- data_image.setAttribute('style', 'height: ' + max_height + 'px');
288
- data_image_div.setAttribute('style', 'min-height: ' + max_height + 'px');
289
- }
290
- if (!(gradioEl.parentNode)) {
291
- const share_btn_container = gradioEl.querySelectorAll('#share-btn-container')[0];
292
- share_btn_container.setAttribute('style', 'width: 0px; height:0px;');
293
- const share_btn_share_icon = gradioEl.querySelectorAll('#share-btn-share-icon')[0];
294
- share_btn_share_icon.setAttribute('style', 'width: 0px; height:0px;');
295
- }
296
- group1.style.display = "none";
297
- group2.style.display = "block";
298
-
299
- window['gradioEl'] = gradioEl;
300
- window['doCheckAction'] = 0;
301
- window['checkAction'] = function checkAction() {
302
- try {
303
- if (window['doCheckAction'] == 0) {
304
- var gallery_items = window['gradioEl'].querySelectorAll('#gallery .gallery-item');
305
- if (gallery_items && gallery_items.length == 2) {
306
- window.clearInterval(window['checkAction_interval']);
307
- window['doCheckAction'] = 1;
308
- gallery_items[gallery_items.length-1].click();
309
- }
310
- }
311
- } catch(e) {
312
- }
313
- }
314
- window['checkAction_interval'] = window.setInterval("window.checkAction()", 500);
315
- }"""
316
-
317
- download_img = """async() => {
318
- Date.prototype.Format = function (fmt) {
319
- var o = {
320
- "M+": this.getMonth() + 1,
321
- "d+": this.getDate(),
322
- "h+": this.getHours(),
323
- "m+": this.getMinutes(),
324
- "s+": this.getSeconds(),
325
- "q+": Math.floor((this.getMonth() + 3) / 3),
326
- "S": this.getMilliseconds()
327
- };
328
- if (/(y+)/.test(fmt))
329
- fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
330
- for (var k in o)
331
- if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
332
- return fmt;
333
- }
334
-
335
- var gradioEl = document.querySelector('body > gradio-app').shadowRoot;
336
- if (!gradioEl) {
337
- gradioEl = document.querySelector('body > gradio-app');
338
- }
339
- const out_image = gradioEl.querySelectorAll('#image_output img')[0];
340
- if (out_image) {
341
- var x=new XMLHttpRequest();
342
- x.open("GET", out_image.src, true);
343
- x.responseType = 'blob';
344
- x.onload = function(e){
345
- var url = window.URL.createObjectURL(x.response)
346
- var a = document.createElement('a');
347
- a.href = url;
348
- a.download = (new Date()).Format("yyyyMMdd_hhmmss");
349
- a.click();
350
- }
351
- x.send();
352
- }
353
- }"""
354
 
355
  image_blocks = gr.Blocks(css=css, title='Image Cleaner')
356
  with image_blocks as demo:
357
- with gr.Group(elem_id="group_1", visible=True) as group_1:
358
  with gr.Box():
359
  with gr.Row(elem_id="gallery_row"):
360
  with gr.Column(elem_id="gallery_col"):
@@ -378,12 +227,18 @@ with image_blocks as demo:
378
  """
379
  )
380
 
381
- with gr.Group(elem_id="group_2", visible=False) as group_2:
382
  with gr.Box(elem_id="work-container"):
383
  with gr.Row(elem_id="input-container"):
384
  with gr.Column():
385
  image_input = gr.Image(source='upload', elem_id="image_upload",tool='sketch', type=f'{image_type}',
386
  label="Upload", show_label=False).style(mobile_collapse=False)
 
 
 
 
 
 
387
  with gr.Row(elem_id="op-container").style(mobile_collapse=False, equal_height=True):
388
  with gr.Column(elem_id="erase-btn-container"):
389
  erase_btn = gr.Button(value = "Erase(⏬)",elem_id="erase-btn").style(
@@ -410,10 +265,18 @@ with image_blocks as demo:
410
  loading_icon = gr.HTML(loading_icon_html, elem_id="loading-icon", visible=True)
411
  share_button = gr.Button("Share to community", elem_id="share-btn", visible=True)
412
 
 
 
 
 
 
 
 
 
413
  erase_btn.click(fn=predict, inputs=[image_input, img_enhancer], outputs=[image_out, gallery, download_container])
414
  download_button.click(None, [], [], _js=download_img)
415
  share_button.click(None, [], [], _js=share_js)
416
 
417
- begin_button.click(fn=None, inputs=[], outputs=[group_1, group_2], _js=start_cleaner)
418
 
419
  image_blocks.launch(server_name='0.0.0.0')
 
4
  import os,sys
5
  import torch
6
  import cv2
 
7
 
8
  import io
9
  import multiprocessing
 
11
  import time
12
  from loguru import logger
13
 
14
+ from utils import *
15
+ from share_btn import *
16
 
17
  from lama_cleaner.model_manager import ModelManager
18
  from lama_cleaner.schema import Config
 
99
  def model_process(image, mask, img_enhancer):
100
  global model,image_enhancer
101
 
102
+ ori_image = image
103
  if mask.shape[0] == image.shape[1] and mask.shape[1] == image.shape[0] and mask.shape[0] != mask.shape[1]:
104
  # rotate image
105
+ ori_image = np.transpose(image[::-1, ...][:, ::-1], axes=(1, 0, 2))[::-1, ...]
106
+ image = ori_image
107
+
108
+ original_shape = ori_image.shape
109
  interpolation = cv2.INTER_CUBIC
110
 
111
  size_limit = 1080
 
169
  log_info = f"image_enhancer_: {(time.time() - start) * 1000}ms, {res_np_img.shape} "
170
  logger.info(log_info)
171
 
172
+ return image, Image.fromarray(ori_image)
173
 
174
  def resize_image(pil_image, new_width=400):
175
  width, height = pil_image.size
 
183
  )
184
 
185
  image_type = 'pil' # filepath'
186
+ def predict(input, img_enhancer):
187
  if input is None:
188
+ return None, [], gr.update(visible=False)
189
  if image_type == 'filepath':
190
  # input: {'image': '/tmp/tmp8mn9xw93.png', 'mask': '/tmp/tmpn5ars4te.png'}
191
  origin_image_bytes = open(input["image"], 'rb').read()
 
198
  mask_pil = input['mask']
199
  image = np.array(image_pil)
200
  mask = np.array(mask_pil.convert("L"))
201
+ output, ori_image = model_process(image, mask, img_enhancer)
202
+ return output, [resize_image(ori_image, new_width=400), resize_image(output, new_width=400)], gr.update(visible=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
 
204
  image_blocks = gr.Blocks(css=css, title='Image Cleaner')
205
  with image_blocks as demo:
206
+ with gr.Group(elem_id="page_1", visible=True) as page_1:
207
  with gr.Box():
208
  with gr.Row(elem_id="gallery_row"):
209
  with gr.Column(elem_id="gallery_col"):
 
227
  """
228
  )
229
 
230
+ with gr.Group(elem_id="page_2", visible=False) as page_2:
231
  with gr.Box(elem_id="work-container"):
232
  with gr.Row(elem_id="input-container"):
233
  with gr.Column():
234
  image_input = gr.Image(source='upload', elem_id="image_upload",tool='sketch', type=f'{image_type}',
235
  label="Upload", show_label=False).style(mobile_collapse=False)
236
+ with gr.Row(elem_id="scroll_x_row"):
237
+ with gr.Column(id="scroll_x_col"):
238
+ gr.HTML("""
239
+ <div id="scroll_x_container" style="width:100%;height:25px;"></div>
240
+ """
241
+ )
242
  with gr.Row(elem_id="op-container").style(mobile_collapse=False, equal_height=True):
243
  with gr.Column(elem_id="erase-btn-container"):
244
  erase_btn = gr.Button(value = "Erase(⏬)",elem_id="erase-btn").style(
 
265
  loading_icon = gr.HTML(loading_icon_html, elem_id="loading-icon", visible=True)
266
  share_button = gr.Button("Share to community", elem_id="share-btn", visible=True)
267
 
268
+ with gr.Row(elem_id="log_row"):
269
+ with gr.Column(id="log_col"):
270
+ gr.HTML("""
271
+ <div id="log_container" style="width:100%;height:auto;">
272
+ </div>
273
+ """
274
+ )
275
+
276
  erase_btn.click(fn=predict, inputs=[image_input, img_enhancer], outputs=[image_out, gallery, download_container])
277
  download_button.click(None, [], [], _js=download_img)
278
  share_button.click(None, [], [], _js=share_js)
279
 
280
+ begin_button.click(fn=None, inputs=[], outputs=[page_1, page_2], _js=start_cleaner)
281
 
282
  image_blocks.launch(server_name='0.0.0.0')