From 9dc40460fdf963e1ea018327ab290c39696ddbf6 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Fri, 25 Sep 2020 19:55:06 -0400 Subject: [PATCH] Support binary comms in nbagg. Fixes #4382. --- lib/matplotlib/backends/backend_nbagg.py | 13 ++++++++----- lib/matplotlib/backends/web_backend/js/mpl.js | 15 +++++++++------ .../backends/web_backend/js/nbagg_mpl.js | 10 +++++++++- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/lib/matplotlib/backends/backend_nbagg.py b/lib/matplotlib/backends/backend_nbagg.py index b921aa0a1d6e..6f41dcf5dfe6 100644 --- a/lib/matplotlib/backends/backend_nbagg.py +++ b/lib/matplotlib/backends/backend_nbagg.py @@ -197,11 +197,14 @@ def send_json(self, content): self.comm.send({'data': json.dumps(content)}) def send_binary(self, blob): - # The comm is ascii, so we always send the image in base64 - # encoded data URL form. - data = b64encode(blob).decode('ascii') - data_uri = "data:image/png;base64,{0}".format(data) - self.comm.send({'data': data_uri}) + if self.supports_binary: + self.comm.send({'blob': 'image/png'}, buffers=[blob]) + else: + # The comm is ASCII, so we send the image in base64 encoded data + # URL form. + data = b64encode(blob).decode('ascii') + data_uri = "data:image/png;base64,{0}".format(data) + self.comm.send({'data': data_uri}) def on_message(self, message): # The 'supports_binary' message is relevant to the diff --git a/lib/matplotlib/backends/web_backend/js/mpl.js b/lib/matplotlib/backends/web_backend/js/mpl.js index 07923fb3f379..59cdadbea268 100644 --- a/lib/matplotlib/backends/web_backend/js/mpl.js +++ b/lib/matplotlib/backends/web_backend/js/mpl.js @@ -499,11 +499,14 @@ mpl.figure.prototype.updated_canvas_event = function () { mpl.figure.prototype._make_on_message_function = function (fig) { return function socket_on_message(evt) { if (evt.data instanceof Blob) { - /* FIXME: We get "Resource interpreted as Image but - * transferred with MIME type text/plain:" errors on - * Chrome. But how to set the MIME type? It doesn't seem - * to be part of the websocket stream */ - evt.data.type = 'image/png'; + var img = evt.data; + if (img.type !== 'image/png') { + /* FIXME: We get "Resource interpreted as Image but + * transferred with MIME type text/plain:" errors on + * Chrome. But how to set the MIME type? It doesn't seem + * to be part of the websocket stream */ + img.type = 'image/png'; + } /* Free the memory for the previous frames */ if (fig.imageObj.src) { @@ -513,7 +516,7 @@ mpl.figure.prototype._make_on_message_function = function (fig) { } fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL( - evt.data + img ); fig.updated_canvas_event(); fig.waiting = false; diff --git a/lib/matplotlib/backends/web_backend/js/nbagg_mpl.js b/lib/matplotlib/backends/web_backend/js/nbagg_mpl.js index 0f538979d19d..607cb98e363b 100644 --- a/lib/matplotlib/backends/web_backend/js/nbagg_mpl.js +++ b/lib/matplotlib/backends/web_backend/js/nbagg_mpl.js @@ -6,6 +6,8 @@ var comm_websocket_adapter = function (comm) { // socket, so there is still some room for performance tuning. var ws = {}; + ws.binaryType = comm.kernel.ws.binaryType; + ws.close = function () { comm.close(); }; @@ -16,8 +18,14 @@ var comm_websocket_adapter = function (comm) { // Register the callback with on_msg. comm.on_msg(function (msg) { //console.log('receiving', msg['content']['data'], msg); + var data = msg['content']['data']; + if (data['blob'] !== undefined) { + data = { + data: new Blob(msg['buffers'], { type: data['blob'] }), + }; + } // Pass the mpl event to the overridden (by mpl) onmessage function. - ws.onmessage(msg['content']['data']); + ws.onmessage(data); }); return ws; };