Home > Net >  Python: Saving NGLView image to PNG
Python: Saving NGLView image to PNG

Time:10-12

I have the following simple task: save a rendered NGLView frame into a .png file and then read the file.

Following this manual I can successfully save an image and open it manually from file explorer. However, in my flow I need to open in using Python and use in downstream jobs right after it was saved. I have the following snippet in my Jupyter Notebook:

import nglview as nv
import ipywidgets as w
import time
import threading

from pathlib import Path
view = nv.demo()
view
def save_image(view):
    img = view.render_image()
    
    while not img.value:
        time.sleep(0.1)
    
    with open("img.png", "wb") as f:
        f.write(img.value)

Path("img.png").unlink(missing_ok=True)

thread = threading.Thread(target=save_image, args=(view, ), daemon=False)
thread.start()

open("img.png", "rb").read()
open("img.png", "rb").read()

The problem is that executing cell#3 I get FileNotFoundError. I found out that file is read by open before it's written in save_image func. If I then execute cell#4 manually - it works fine. However, if I execute all 4 cells at once (using re-run button in the notebook) - I get the exception. Seems like the image is rendered only when main thread finishes its job.

Adding thread.join() leads to infinite loop (i.e. the image is never rendered). Trying to await for image to be rendered with while-loop and sleep after the thread was started is also not working.

How can I let Python wait for image to be rendered and saved before reading the file?

python-3.8.10; nglview-3.0.3; OS - Win, MacOS

CodePudding user response:

Generally, JS rendering is invoked only after other jobs are executed, i.e. awaiting for render and then reading a file is not possible. That's why all work with the image should happen in save_image function.

See here

  • Related