"""OracleZoom demo: upload a photo, watch it zoom 4x and deeper.""" import gradio as gr import spaces from PIL import Image, ImageDraw import geometry import video import zoom MODELS = zoom.Models() UPSCALE = 4 MAX_STEPS = 8 ACCENT = "#f5b942" SAMPLES = ["0479", "0064", "0245", "0393", "0457"] # Shipped output of a real run, so the page shows the payoff before anyone spends any quota. EXAMPLE_INPUT = "samples/example_1x.png" EXAMPLE_CLIP = "samples/example_zoom.mp4" EXAMPLE_LEVELS = [(EXAMPLE_INPUT, "input")] + \ [(f"samples/example_{f}x.png", f"{f}x") for f in (4, 16, 64, 256)] EXAMPLE_COMPARE = ("samples/example_256x_input.png", "samples/example_256x.png") EXAMPLE_NOTE = "_An example run. Upload a photo above to make your own._" HEADER = """

OracleZoom 🔎

Zoom into any photo far past what it holds. Four steps of 4x take you to 256x, each one drawn from the last. Push it to eight steps if you want.

Paper  Â·  Code  Â·  Project page  Â·  Model

""" BIBTEX = """@misc{dipta2026oraclezoomonpolicyselfdistillationinspired, title = {OracleZoom: On-Policy Self-Distillation Inspired Reference-Constrained Recursive Image Super Resolution}, author = {Shubhashis Roy Dipta and Sourajit Saha and Shaswati Saha and Nobin Sarwar}, year = {2026}, eprint = {2609.06490}, archivePrefix = {arXiv}, primaryClass = {cs.CV}, url = {https://arxiv.org/abs/2609.06490} }""" CSS = """ #hero video {border-radius:12px} .contain {max-width:1400px !important} footer {display:none !important} #zoom-target img {cursor:crosshair} /* a deep run wraps to two rows; keep any scrollbar from rendering light on a dark theme */ #levels, #levels * {scrollbar-color: var(--border-color-primary) transparent} """ def label(factor): return "input" if factor == 1 else f"{factor}x" def preview(image, levels, cx, cy): """Show where the zoom will go, so nobody spends a run to find out. Falls back to the shipped example when nothing is uploaded yet. Returning None here instead would blank the box the moment a visitor touched any slider, taking the one thing that explains what the amber boxes mean with it. """ canvas = geometry.resize_and_center_crop( image if image is not None else Image.open(EXAMPLE_INPUT)).convert("RGB") rects = geometry.nested_rects(canvas.size, int(levels), UPSCALE, (cx, cy)) dimmed = Image.blend(canvas, Image.new("RGB", canvas.size, (0, 0, 0)), 0.45) dimmed.paste(canvas.crop(rects[0]), rects[0][:2]) draw = ImageDraw.Draw(dimmed) for rect in rects: if rect[2] - rect[0] >= 3: draw.rectangle(rect, outline=ACCENT, width=2) return dimmed def pick_point(evt: gr.SelectData): x, y = evt.index return x / geometry.PROCESS_SIZE, y / geometry.PROCESS_SIZE def _gallery_paths(gallery): """The (path, label) pairs Gradio hands back for a Gallery value.""" out = [] for item in gallery or []: img = item.get("image", item) if isinstance(item, dict) else item path = img.get("path") if isinstance(img, dict) else img out.append((path, (item.get("caption") if isinstance(item, dict) else None) or "")) return out def pick_scale(gallery, cx, cy, choice): """Rebuild the comparison at whichever scale was asked for. The left side is the plain enlargement that fed that step, which is the previous level cropped and scaled back up. Recomputing it from the levels already on screen keeps this on the CPU, so switching scales costs no GPU quota. """ levels = _gallery_paths(gallery) labels = [lbl for _, lbl in levels] if choice not in labels: return gr.skip() i = labels.index(choice) if i == 0: return gr.skip() prev = Image.open(levels[i - 1][0]).convert("RGB") blurry = geometry.zoom_window(prev, UPSCALE, (cx, cy)).resize(prev.size, Image.BICUBIC) return blurry, Image.open(levels[i][0]).convert("RGB") def scale_choices(levels): return [label(UPSCALE ** n) for n in range(1, int(levels) + 1)] GALLERY_ROW_H = 245 def gallery_shape(levels): """One row up to five levels, two beyond. Tall enough that neither row ever scrolls.""" items = int(levels) + 1 rows = 1 if items <= 5 else 2 return gr.update(columns=-(-items // rows), rows=rows, height=GALLERY_ROW_H * rows) def estimate_duration(image, levels, cx, cy): # Checked against the visitor's remaining quota BEFORE the run, so a loose number locks out # low-quota visitors and a tight one gets the run killed mid-way. Measured warm on ZeroGPU: # 6.4s fixed, 3.2s per level. Near double that, to survive a cold worker streaming weights. return int(12 + 6 * int(levels)) def _stream(image, levels, cx, cy): if image is None: raise gr.Error("Upload a photo first.") levels = int(levels) gallery, prompts, frames, compare = [], [], [], None for step, factor, prompt, blurry, result in zoom.zoom(MODELS, image, levels, UPSCALE, (cx, cy)): frames.append(result) gallery.append((result, label(factor))) if step: compare = (blurry, result) prompts.append(f"**{label(factor)}**   {prompt or '_(no prompt)_'}") left = levels - step if not step: status = f"Warmed up. Zooming {levels} step{'s' if levels > 1 else ''}…" elif left: status = f"At **{label(factor)}**, {left} step{'s' if left > 1 else ''} to go…" else: status = f"At **{label(factor)}**. Rendering the clip…" # First yield clears any clip left from the previous run; later ones leave it alone. yield (status, (None if not step else gr.skip()), gallery, compare, "\n\n".join(prompts), gr.skip()) yield ("Done. 🔎", video.render(frames, UPSCALE, (cx, cy)), gallery, compare, "\n\n".join(prompts), gr.update(choices=scale_choices(levels), value=label(UPSCALE ** levels))) @spaces.GPU(duration=estimate_duration) def run(image, levels, cx, cy): yield from _stream(image, levels, cx, cy) @spaces.GPU(duration=estimate_duration(None, 4, 0, 0)) def run_example(image): """One input, so the examples render as thumbnails instead of a four-column table. Its results are cached, which is how a visitor with no quota left still sees output.""" yield from _stream(image, 4, 0.5, 0.5) def _example_scale_options(): """Keep the picker's starting options honest about the shipped example's depth.""" return scale_choices(len(EXAMPLE_LEVELS) - 1) with gr.Blocks(theme=gr.themes.Soft(primary_hue="amber"), css=CSS, title="OracleZoom: zoom past 256x") as demo: gr.HTML(HEADER) # Three wide rows, not one tall stack: set it up, watch it, then inspect it. Each row uses # the full width, which is what keeps four large visuals from queueing up vertically. with gr.Row(equal_height=False): with gr.Column(scale=4): image = gr.Image(label="Your photo", type="pil", height=300, sources=["upload", "clipboard"]) # Seeded with the example so the box overlay explains itself before any upload. target = gr.Image(value=preview(None, 4, 0.5, 0.5), elem_id="zoom-target", label="Click to move the zoom point", type="pil", interactive=False, height=340, show_download_button=False) levels = gr.Slider(1, MAX_STEPS, value=4, step=1, label="Zoom steps", info=f"Each step is {UPSCALE}x. 4 steps reach 256x, " f"{MAX_STEPS} reach {UPSCALE ** MAX_STEPS}x. " f"Fewer steps finish sooner.") with gr.Row(): cx = gr.Slider(0, 1, value=0.5, step=0.01, label="Horizontal", elem_id="zoom-x") cy = gr.Slider(0, 1, value=0.5, step=0.01, label="Vertical", elem_id="zoom-y") go = gr.Button("🔎 Zoom in", variant="primary", size="lg") status = gr.Markdown("Showing an example. Upload a photo, then press **Zoom in**.") with gr.Column(scale=6): clip = gr.Video(value=EXAMPLE_CLIP, label="The zoom", elem_id="hero", autoplay=True, loop=True, show_share_button=True, height=470) with gr.Row(): gallery = gr.Gallery(value=EXAMPLE_LEVELS, label="Every level, start to finish", elem_id="levels", object_fit="cover", show_download_button=True, **{k: v for k, v in gallery_shape(len(EXAMPLE_LEVELS) - 1).items() if k != "__type__"}) with gr.Row(equal_height=False): with gr.Column(scale=5): scale = gr.Radio(_example_scale_options(), value=EXAMPLE_LEVELS[-1][1], label="Compare at", info="Left is the plain enlargement that step began from, " "right is what OracleZoom drew. Switching is free.") compare = gr.ImageSlider(value=EXAMPLE_COMPARE, height=480, elem_id="compare", show_label=False) with gr.Column(scale=5): gr.Markdown("##### Vision Language Model at each step:") prompts = gr.Markdown(EXAMPLE_NOTE) with gr.Row(): gr.Examples( examples=[f"samples/{n}.png" for n in SAMPLES], inputs=[image], outputs=[status, clip, gallery, compare, prompts, scale], fn=run_example, cache_examples=True, label="Or try one of these (already computed)", ) controls = [image, levels, cx, cy] for c in controls: c.change(preview, controls, target, show_api=False) target.select(pick_point, None, [cx, cy], show_api=False) # Reshape before the run, not after, so the strip does not resize under the results. levels.change(gallery_shape, levels, gallery, show_api=False) go.click(run, controls, [status, clip, gallery, compare, prompts, scale]) scale.change(pick_scale, [gallery, cx, cy, scale], compare, show_api=False) gr.Markdown("### Cite our work") gr.Code(value=BIBTEX, language=None, show_label=False, container=False) if __name__ == "__main__": demo.queue(max_size=20).launch()