Spaces:
Running on Zero
Running on Zero
Fix example workspace zoom initialization
Browse files
app.py
CHANGED
|
@@ -52,6 +52,8 @@ model = AutoModel.from_pretrained(MODEL_NAME, _attn_implementation=_attn_impl, t
|
|
| 52 |
BASE_SIZE = 1024
|
| 53 |
IMAGE_SIZE = 768
|
| 54 |
CROP_MODE = True
|
|
|
|
|
|
|
| 55 |
WORKSPACE_DEFAULT_SCALE = 89
|
| 56 |
GROUNDING_PATTERN = re.compile(r'<\|ref\|>(.*?)<\|/ref\|><\|det\|>(.*?)<\|/det\|>', re.DOTALL)
|
| 57 |
INFER_DEBUG_FILTERS = ['PATCHES', '====', 'BASE:', 'directly resize', 'NO PATCHES', 'torch.Size', '%|']
|
|
@@ -1354,21 +1356,45 @@ def _scale_workspace_image(img, workspace_scale):
|
|
| 1354 |
scale = max(60, min(220, int(workspace_scale)))
|
| 1355 |
except Exception:
|
| 1356 |
scale = WORKSPACE_DEFAULT_SCALE
|
| 1357 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1358 |
return img
|
| 1359 |
-
|
| 1360 |
-
|
| 1361 |
-
new_h = max(1, int(round(img.height * ratio)))
|
| 1362 |
resample = Image.Resampling.BILINEAR if hasattr(Image, "Resampling") else Image.BILINEAR
|
| 1363 |
return img.resize((new_w, new_h), resample)
|
| 1364 |
|
| 1365 |
-
def
|
| 1366 |
-
img = load_image(file_path, page_num)
|
| 1367 |
if img is None:
|
| 1368 |
return None, None, None
|
| 1369 |
display_img = _scale_workspace_image(img, workspace_scale)
|
| 1370 |
return display_img, (int(display_img.width), int(display_img.height)), display_img
|
| 1371 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1372 |
def sync_workspace_state(editor_value, current_base_image):
|
| 1373 |
background = _extract_editor_background(editor_value)
|
| 1374 |
if isinstance(background, Image.Image):
|
|
@@ -1451,7 +1477,7 @@ with gr.Blocks(**blocks_kwargs) as demo:
|
|
| 1451 |
label="Image Workspace",
|
| 1452 |
show_label=False,
|
| 1453 |
type="pil",
|
| 1454 |
-
height=
|
| 1455 |
**editor_kwargs,
|
| 1456 |
)
|
| 1457 |
except TypeError:
|
|
@@ -1459,21 +1485,21 @@ with gr.Blocks(**blocks_kwargs) as demo:
|
|
| 1459 |
region_editor = gr.ImageEditor(
|
| 1460 |
label="Image Workspace",
|
| 1461 |
show_label=False,
|
| 1462 |
-
height=
|
| 1463 |
**editor_kwargs,
|
| 1464 |
)
|
| 1465 |
except TypeError:
|
| 1466 |
region_editor = gr.ImageEditor(
|
| 1467 |
label="Image Workspace",
|
| 1468 |
show_label=False,
|
| 1469 |
-
height=
|
| 1470 |
)
|
| 1471 |
else:
|
| 1472 |
region_editor = gr.Paint(
|
| 1473 |
label="Image Workspace",
|
| 1474 |
show_label=False,
|
| 1475 |
type="pil",
|
| 1476 |
-
height=
|
| 1477 |
**editor_kwargs,
|
| 1478 |
)
|
| 1479 |
else:
|
|
@@ -1529,10 +1555,19 @@ with gr.Blocks(**blocks_kwargs) as demo:
|
|
| 1529 |
"examples/2022-0922 Section 15 Notes.png",
|
| 1530 |
]
|
| 1531 |
if HAS_REGION_WORKSPACE and region_editor is not None:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1532 |
gr.Examples(
|
| 1533 |
label="Image Examples (click thumbnail to load into workspace)",
|
| 1534 |
examples=image_examples,
|
| 1535 |
-
inputs=[
|
|
|
|
|
|
|
|
|
|
| 1536 |
cache_examples=False,
|
| 1537 |
)
|
| 1538 |
else:
|
|
@@ -1560,7 +1595,7 @@ with gr.Blocks(**blocks_kwargs) as demo:
|
|
| 1560 |
2. Choose **Input Scope**:
|
| 1561 |
- `Entire Page` for the full page.
|
| 1562 |
- `Selected Region` for a specific area.
|
| 1563 |
-
2a. Workspace
|
| 1564 |
3. For `Selected Region`, use the **Image Workspace**:
|
| 1565 |
- Recommended: freehand selection (draw/highlight target); app uses an automatic bounding box around your marks.
|
| 1566 |
- Optional rectangle selection: use the **Crop** tool.
|
|
|
|
| 52 |
BASE_SIZE = 1024
|
| 53 |
IMAGE_SIZE = 768
|
| 54 |
CROP_MODE = True
|
| 55 |
+
WORKSPACE_EDITOR_HEIGHT = 640
|
| 56 |
+
WORKSPACE_EDITOR_WIDTH_EST = 980
|
| 57 |
WORKSPACE_DEFAULT_SCALE = 89
|
| 58 |
GROUNDING_PATTERN = re.compile(r'<\|ref\|>(.*?)<\|/ref\|><\|det\|>(.*?)<\|/det\|>', re.DOTALL)
|
| 59 |
INFER_DEBUG_FILTERS = ['PATCHES', '====', 'BASE:', 'directly resize', 'NO PATCHES', 'torch.Size', '%|']
|
|
|
|
| 1356 |
scale = max(60, min(220, int(workspace_scale)))
|
| 1357 |
except Exception:
|
| 1358 |
scale = WORKSPACE_DEFAULT_SCALE
|
| 1359 |
+
# Target a predictable initial in-canvas zoom by fitting image into
|
| 1360 |
+
# a virtual viewport derived from editor size and requested scale.
|
| 1361 |
+
target_ratio = max(0.6, min(2.2, scale / 100.0))
|
| 1362 |
+
max_w = max(1, int(round(WORKSPACE_EDITOR_WIDTH_EST / target_ratio)))
|
| 1363 |
+
max_h = max(1, int(round(WORKSPACE_EDITOR_HEIGHT / target_ratio)))
|
| 1364 |
+
fit_ratio = min(max_w / max(1, img.width), max_h / max(1, img.height), 1.0)
|
| 1365 |
+
if fit_ratio >= 0.999:
|
| 1366 |
return img
|
| 1367 |
+
new_w = max(1, int(round(img.width * fit_ratio)))
|
| 1368 |
+
new_h = max(1, int(round(img.height * fit_ratio)))
|
|
|
|
| 1369 |
resample = Image.Resampling.BILINEAR if hasattr(Image, "Resampling") else Image.BILINEAR
|
| 1370 |
return img.resize((new_w, new_h), resample)
|
| 1371 |
|
| 1372 |
+
def _prepare_workspace_image(img, workspace_scale=WORKSPACE_DEFAULT_SCALE):
|
|
|
|
| 1373 |
if img is None:
|
| 1374 |
return None, None, None
|
| 1375 |
display_img = _scale_workspace_image(img, workspace_scale)
|
| 1376 |
return display_img, (int(display_img.width), int(display_img.height)), display_img
|
| 1377 |
|
| 1378 |
+
def load_image_with_size(file_path, page_num=1, workspace_scale=WORKSPACE_DEFAULT_SCALE):
|
| 1379 |
+
img = load_image(file_path, page_num)
|
| 1380 |
+
return _prepare_workspace_image(img, workspace_scale)
|
| 1381 |
+
|
| 1382 |
+
def load_example_into_workspace(example_value):
|
| 1383 |
+
if example_value is None:
|
| 1384 |
+
return None, None, None
|
| 1385 |
+
if isinstance(example_value, Image.Image):
|
| 1386 |
+
img = example_value
|
| 1387 |
+
else:
|
| 1388 |
+
maybe_rgba = _to_rgba_image(example_value)
|
| 1389 |
+
if maybe_rgba is None:
|
| 1390 |
+
return None, None, None
|
| 1391 |
+
img = maybe_rgba.convert("RGB")
|
| 1392 |
+
return _prepare_workspace_image(img, WORKSPACE_DEFAULT_SCALE)
|
| 1393 |
+
|
| 1394 |
+
def load_example_into_workspace_and_reset(example_value):
|
| 1395 |
+
display_img, base_size, base_img = load_example_into_workspace(example_value)
|
| 1396 |
+
return display_img, base_size, base_img, [], [], "No saved regions.", None
|
| 1397 |
+
|
| 1398 |
def sync_workspace_state(editor_value, current_base_image):
|
| 1399 |
background = _extract_editor_background(editor_value)
|
| 1400 |
if isinstance(background, Image.Image):
|
|
|
|
| 1477 |
label="Image Workspace",
|
| 1478 |
show_label=False,
|
| 1479 |
type="pil",
|
| 1480 |
+
height=WORKSPACE_EDITOR_HEIGHT,
|
| 1481 |
**editor_kwargs,
|
| 1482 |
)
|
| 1483 |
except TypeError:
|
|
|
|
| 1485 |
region_editor = gr.ImageEditor(
|
| 1486 |
label="Image Workspace",
|
| 1487 |
show_label=False,
|
| 1488 |
+
height=WORKSPACE_EDITOR_HEIGHT,
|
| 1489 |
**editor_kwargs,
|
| 1490 |
)
|
| 1491 |
except TypeError:
|
| 1492 |
region_editor = gr.ImageEditor(
|
| 1493 |
label="Image Workspace",
|
| 1494 |
show_label=False,
|
| 1495 |
+
height=WORKSPACE_EDITOR_HEIGHT,
|
| 1496 |
)
|
| 1497 |
else:
|
| 1498 |
region_editor = gr.Paint(
|
| 1499 |
label="Image Workspace",
|
| 1500 |
show_label=False,
|
| 1501 |
type="pil",
|
| 1502 |
+
height=WORKSPACE_EDITOR_HEIGHT,
|
| 1503 |
**editor_kwargs,
|
| 1504 |
)
|
| 1505 |
else:
|
|
|
|
| 1555 |
"examples/2022-0922 Section 15 Notes.png",
|
| 1556 |
]
|
| 1557 |
if HAS_REGION_WORKSPACE and region_editor is not None:
|
| 1558 |
+
image_examples_input = gr.Image(
|
| 1559 |
+
label="Example Loader",
|
| 1560 |
+
type="pil",
|
| 1561 |
+
visible=False,
|
| 1562 |
+
show_label=False,
|
| 1563 |
+
)
|
| 1564 |
gr.Examples(
|
| 1565 |
label="Image Examples (click thumbnail to load into workspace)",
|
| 1566 |
examples=image_examples,
|
| 1567 |
+
inputs=[image_examples_input],
|
| 1568 |
+
outputs=[region_editor, workspace_base_size, workspace_base_image, selected_regions_state, selected_regions_gallery, selection_status, drawn_mask_state],
|
| 1569 |
+
fn=load_example_into_workspace_and_reset,
|
| 1570 |
+
run_on_click=True,
|
| 1571 |
cache_examples=False,
|
| 1572 |
)
|
| 1573 |
else:
|
|
|
|
| 1595 |
2. Choose **Input Scope**:
|
| 1596 |
- `Entire Page` for the full page.
|
| 1597 |
- `Selected Region` for a specific area.
|
| 1598 |
+
2a. Workspace targets about **89% initial zoom** by default to keep small math readable while avoiding extra zoom adjustments.
|
| 1599 |
3. For `Selected Region`, use the **Image Workspace**:
|
| 1600 |
- Recommended: freehand selection (draw/highlight target); app uses an automatic bounding box around your marks.
|
| 1601 |
- Optional rectangle selection: use the **Crop** tool.
|