"""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_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

""" LIMITS = ("Past the first step or two there is no ground truth left to recover, so the deep " "levels are **plausible detail, not measured detail**. The zoom is a crop of your " "photo, not a real lens moving closer.") 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:grab} #zoom-target img:active {cursor:grabbing} /* 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} """ # Drag the zoom point straight on the preview. Throttled, because every move asks the server to # redraw. Clicking and the two sliders both still work if this ever stops matching the DOM. DRAG_JS = """ () => { if (window.__ozDrag) return; // load can fire more than once; keep one state const S = window.__ozDrag = {on: false, last: 0}; const send = (e, force) => { const img = document.querySelector('#zoom-target img'); if (!img) return; const now = Date.now(); if (!force && now - S.last < 120) return; S.last = now; const r = img.getBoundingClientRect(); const at = (v, lo, span) => Math.min(Math.max((v - lo) / span, 0), 1); for (const [id, v] of [['zoom-x', at(e.clientX, r.left, r.width)], ['zoom-y', at(e.clientY, r.top, r.height)]]) { const el = document.querySelector('#' + id + ' input[type=range]'); if (!el) continue; el.value = v.toFixed(2); el.dispatchEvent(new Event('input', {bubbles: true})); } }; // delegated off document, so Gradio swapping the img or the sliders mid-drag is harmless document.addEventListener('mousedown', e => { if (!e.target.closest('#zoom-target img')) return; S.on = true; e.preventDefault(); send(e, true); }, true); document.addEventListener('mousemove', e => { if (S.on) send(e, false); }); document.addEventListener('mouseup', e => { if (S.on) { S.on = false; send(e, true); } }); } """ 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 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 = [], [], [] 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: 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, "\n\n".join(prompts) yield "Done. 🔎", video.render(frames, UPSCALE, (cx, cy)), gallery, "\n\n".join(prompts) @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) with gr.Blocks(theme=gr.themes.Soft(primary_hue="amber"), css=CSS, title="OracleZoom: zoom past 256x") as demo: gr.HTML(HEADER) with gr.Row(): 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="Drag 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") with gr.Column(scale=6): status = gr.Markdown("Upload a photo, then press **Zoom in**.") clip = gr.Video(value=EXAMPLE_CLIP, label="The zoom", elem_id="hero", autoplay=True, loop=True, show_share_button=True, height=400) gallery = gr.Gallery(value=EXAMPLE_LEVELS, label="Every level", columns=5, height=205, elem_id="levels", object_fit="cover", show_download_button=True) gr.Markdown("##### Vision Language Model at each step:") prompts = gr.Markdown(EXAMPLE_NOTE) controls = [image, levels, cx, cy] outputs = [status, clip, gallery, prompts] for c in controls: c.change(preview, controls, target, show_api=False) target.select(pick_point, None, [cx, cy], show_api=False) go.click(run, controls, outputs) gr.Examples( examples=[f"samples/{n}.png" for n in SAMPLES], inputs=[image], outputs=outputs, fn=run_example, cache_examples=True, label="Or try one of these (already computed, costs you nothing)", ) gr.Markdown(f"{LIMITS} See the [paper](https://arxiv.org/abs/2609.06490) for the claims we " f"do and do not make.\n\n### Cite our work") gr.Code(value=BIBTEX, language=None, show_label=False, container=False) demo.load(None, None, None, js=DRAG_JS, show_api=False) if __name__ == "__main__": demo.queue(max_size=20).launch()