Skip to content

Conversation

@ManifoldFR
Copy link
Contributor

This PR follows meshcat-dev/meshcat#85.

It adds a new get_image() method to meshcat.Visualizer. This relies on the new capture_image command added in meshcat-dev/meshcat#85 which queries an image returned to the Meshcat client as a PNG in base64 data URI form.

Design

On the Python side, the WebsocketHandler awaits the response from the Meshcat client, and when it receives the JSON from the frontend, the on_message() callback is triggered, which sends the PNG (turned into a sequence of bytes) over the ZMQ bridge.

Limitations

The design is not completely robust yet. It requires the browser window be already open to get a response in the client (the visualizer will block until then).
Maybe this behavior can be fixed by using something else to get the PNG render.

* uses new command added to index.js
* takes the b64 encoded dataURI from websocket, sends bytes over zmq
* makes use of queue.Queue pointless, removed
* also removed method ws_receive_image_process_data()
Copy link
Collaborator

@rdeits rdeits left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will certainly be useful, thank you!

class CaptureImage:
__slots__ = ["save_path"]
def __init__(self, save_path=""):
self.save_path = save_path
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like save_path isn't actually used anywhere, since the image is returned as a PIL.Image (a good idea) rather than being written to disk. Can we just remove save_path entirely?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, let's remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commit c7a4c73 adresses this, though I had to insert a UTF-8 encoded empty string to make sure the length of the frames arg is right

self.zmq_socket.send_multipart([
cmd_data["type"].encode("utf-8"),
cmd_data["save_path"].encode("utf-8"),
"".encode("utf-8"),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I was talking about. This makes sure frames in ZMQSocketBridge.forward_to_websockets has the right length.

Ideally we could change that method to be more flexible, too

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, makes sense. I think this is fine for now.

elif cmd == "wait":
self.ioloop.add_callback(self.wait_for_websockets)
elif cmd == "capture_image":
save_path = frames[1].decode("utf-8")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line was actually useless so I removed it

"tornado >= 4.0.0",
"pyzmq >= 17.0.0",
"pyngrok >= 4.1.6",
"pillow >= 7.0.0"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the requirement for PIL

Copy link
Collaborator

@rdeits rdeits left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks

vis.path = path
return vis

viewer = meshcat.Visualizer()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line failed the linting, don't know where it came from

@ManifoldFR
Copy link
Contributor Author

@rdeits Can we get a new release on PyPI after merging?

@rdeits
Copy link
Collaborator

rdeits commented Aug 3, 2021

Yup, I'll do that as soon as this is merged.

@codecov-commenter
Copy link

codecov-commenter commented Aug 3, 2021

Codecov Report

Merging #93 (decd6ae) into master (3460c7f) will decrease coverage by 1.32%.
The diff coverage is 29.03%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #93      +/-   ##
==========================================
- Coverage   74.85%   73.52%   -1.33%     
==========================================
  Files          11       11              
  Lines        1006     1035      +29     
==========================================
+ Hits          753      761       +8     
- Misses        253      274      +21     
Impacted Files Coverage Δ
src/meshcat/servers/zmqserver.py 29.23% <11.76%> (-1.10%) ⬇️
src/meshcat/visualizer.py 75.70% <45.45%> (-3.69%) ⬇️
src/meshcat/commands.py 92.45% <66.66%> (-1.55%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3460c7f...decd6ae. Read the comment docs.

@rdeits rdeits merged commit 20e4652 into meshcat-dev:master Aug 3, 2021
traversaro added a commit to regro-cf-autotick-bot/meshcat-python-feedstock that referenced this pull request Aug 3, 2021
@ManifoldFR ManifoldFR deleted the feature/capture_image branch August 3, 2021 09:01
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

Successfully merging this pull request may close these issues.

3 participants