Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

interactive image force_reload behavior #2566

Closed
scottrcarlson opened this issue Feb 18, 2024 · 8 comments
Closed

interactive image force_reload behavior #2566

scottrcarlson opened this issue Feb 18, 2024 · 8 comments

Comments

@scottrcarlson
Copy link

scottrcarlson commented Feb 18, 2024

Description

This works perfectly fine:

cam1 = ui.interactive_image(cam1_url)
ui.button('Refresh', on_click=cam1.force_reload).style('font-size: 150%; font-weight: 300')

However, if I were to execute cam1.force_reload() inside a function, or lambda, it does not seem do anything. For example, i'd like to setup a ui.timer() to call a function that reloads the image. I've tried a few variations using lambda, callback= and even ui.refreshable to attempt to resolve.

The only way .force_reload seems to function is when utilized in on_click.

Any advice or guidance would be greatly appreciated!

@falkoschindler
Copy link
Contributor

@scottrcarlson Refreshing an interactive image via ui.timer should work like this:

img = ui.interactive_image('https://picsum.photos/640/360')
ui.timer(1.0, img.force_reload)

Maybe you can share your code to see what you're doing differently?

@falkoschindler falkoschindler added the question Further information is requested label Feb 18, 2024
@scottrcarlson
Copy link
Author

That worked just fine. I don't know how I didn't try that permutation!

Thank you!

@scottrcarlson
Copy link
Author

Resolved.

@rp10007
Copy link

rp10007 commented Oct 16, 2024

I have a slightly different version of this same question that may just be me misunderstanding what should happen: I have an interactive image that reloads fine when force_reload is called in its own mousehandler, but I would like it to also reload (with changes) when some buttons are pushed.

src = to_scan #image created by picam2.capture_image(), should be PIL form
ii = ui.interactive_image(src, on_mouse=mouse_handler, events=['mousedown', 'mouseup'], cross=True)

ui.button('Zoom', on_click=cropsrc)

def cropsrc():  
    global src
    print (int(ii.boxxpos), int(ii.boxypos),  int(ii.boxxpos+ii.boxwid), int(ii.boxypos + ii.boxht))
    src = to_scan.crop((int(ii.boxxpos), int(ii.boxypos),  int(ii.boxxpos+ii.boxwid), int(ii.boxypos + ii.boxht)))
    print("cropped")
    ii.force_reload()

(pls forgive the print statements; I'm coding this for a headless raspberry pi)
Anyway, when I click to do things inside the image, that works reasonably well if slowly. But if I click the Zoom button, I get the console printouts of my coordinates and a message that the cropping happened, but the image does not reload.

Is the reload not happening because something about the cropped image is malformed, or for other reasons?

@rodja
Copy link
Member

rodja commented Oct 16, 2024

The modification of src is not automatically updating the value in the interactive image. Try ii.source = src before the force_reload.

@falkoschindler falkoschindler removed the question Further information is requested label Oct 16, 2024
@rp10007
Copy link

rp10007 commented Oct 17, 2024

Alas, nope. I think the fact that src is a PIL image rather than a file that can have a timestamp appended may be part of the problem. I've tried adding some svg content to the new image to force a reload, but nope. (Also tried wrapping in a refreshable function, still nope.) I don't know whether this is part of the same problem, but the new picture button, which takes an image with the same camera parameters as the start of the file, results in a broken-image icon where the new picture should be; if I try to copy that info from the browser right-click it's a pile of base64 that says it's data:image/png. And if I try to copy the URL, it's also data:imag/ png, with a much smaller pile of data terminating in _"?nicegui_t=1729208047.7239652"

Hope that helps someone figure out what's going on.

@rodja
Copy link
Member

rodja commented Oct 18, 2024

Oh wow. Thanks for the clarification @scottrcarlson. I could reproduce this bug with

src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
img = ui.interactive_image(src).classes('w-64')
ui.button('Force reload', on_click=img.force_reload)

If the button is pressed, the image is not shown anymore. I guess the appending of a timestamp breaks the data:... url.

@rodja
Copy link
Member

rodja commented Oct 18, 2024

Force reload makes only sense on network urls, not on base64 encoded data. The browser reloads when the source changes. Thats why we append a timestamp to the url (which modifies the url without changing the actual target where the browser loads the image). If a different data url is set on source, the browser will automatically update the rendering. I created #3895 to show a warning in such cases.

@scottrcarlson for your specific case you can simply exchange the force reload with an update of source:

src = to_scan #image created by picam2.capture_image(), should be PIL form
ii = ui.interactive_image(src, on_mouse=mouse_handler, events=['mousedown', 'mouseup'], cross=True)

ui.button('Zoom', on_click=cropsrc)

def cropsrc():  
    global src
    print (int(ii.boxxpos), int(ii.boxypos),  int(ii.boxxpos+ii.boxwid), int(ii.boxypos + ii.boxht))
    ii.source = to_scan.crop((int(ii.boxxpos), int(ii.boxypos),  int(ii.boxxpos+ii.boxwid), int(ii.boxypos + ii.boxht)))
    print("cropped")

falkoschindler added a commit that referenced this issue Oct 25, 2024
This PR attempts to help the user understand that `force_reload` only
makes sense on network urls. See
#2566 (comment)
more

---------

Co-authored-by: Falko Schindler <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants