Python 3.x 以破折号/绘图方式显示PIL图像

Python 3.x 以破折号/绘图方式显示PIL图像,python-3.x,flask,plotly,plotly-dash,Python 3.x,Flask,Plotly,Plotly Dash,我一直在开发我的Dash web应用程序,现在正在考虑在我的虚拟机上托管它 设置环境后,我无法直接加载html.Img元素中的PIL Image对象。 渲染它们时,将弹出一个错误,并通知我我的PIL图像不可序列化 这让我觉得很奇怪,可能不是一个精心策划的错误,但我有完全相同的代码、库和图像,在我的虚拟机上导致错误,但在我的工作站上运行平稳 加载并执行一些预处理后,my Image对象被传递到html组件,如图所示: grid\u main\u图像= 同样,序列化错误只发生在我的VM上,而不发生在

我一直在开发我的Dash web应用程序,现在正在考虑在我的虚拟机上托管它

设置环境后,我无法直接加载
html.Img
元素中的
PIL Image
对象。 渲染它们时,将弹出一个错误,并通知我我的PIL图像不可序列化

这让我觉得很奇怪,可能不是一个精心策划的错误,但我有完全相同的代码、库和图像,在我的虚拟机上导致错误,但在我的工作站上运行平稳

加载并执行一些预处理后,my Image对象被传递到html组件,如图所示:

grid\u main\u图像=

同样,序列化错误只发生在我的VM上,而不发生在我的本地计算机上。 这是完整的错误/回溯

Traceback (most recent call last):
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/dash/dash.py", line 1227, in add_context
    cls=plotly.utils.PlotlyJSONEncoder
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/_plotly_utils/utils.py", line 49, in encode
    encoded_o = super(PlotlyJSONEncoder, self).encode(o)
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/_plotly_utils/utils.py", line 119, in default
    return _json.JSONEncoder.default(self, obj)
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Image is not JSON serializable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 2463, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 2449, in wsgi_app
    response = self.handle_exception(e)
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 1866, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 2446, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 1951, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 1820, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 1949, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/flask/app.py", line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/dash/dash.py", line 1291, in dispatch
    response.set_data(self.callback_map[output]['callback'](*args))
  File "/home/aegilsson/anaconda3/envs/diamond/lib/python3.7/site-packages/dash/dash.py", line 1242, in add_context
    ).replace('    ', ''))
dash.exceptions.InvalidCallbackReturnValue: 
The callback for property `children`
of component `tabs-content` returned a value
which is not JSON serializable.

In general, Dash properties can only be
dash components, strings, dictionaries, numbers, None,
or lists of those.

您需要对图像进行base64编码并添加一些HTML标题

def pil_to_b64(im, enc_format="png", **kwargs):
    """
    Converts a PIL Image into base64 string for HTML displaying
    :param im: PIL Image object
    :param enc_format: The image format for displaying. If saved the image will have that extension.
    :return: base64 encoding
    """

    buff = BytesIO()
    im.save(buff, format=enc_format, **kwargs)
    encoded = base64.b64encode(buff.getvalue()).decode("utf-8")

    return encoded

html.Img(id="my-img",className="image", src="data:image/png;base64, " + pil_to_b64(pil_img))

信用:@Atli的评论为我指明了正确的方向。

建议您尝试将src更改为children(如中),因为src需要字符串,而您发送的对象不是字符串。此外,您可能希望转换base64中的pillow对象(从)-这将得到一个字符串,您可以将其包含在childrenThank中以供输入。我设法在
def pil_to_b64(im, enc_format="png", **kwargs):
    """
    Converts a PIL Image into base64 string for HTML displaying
    :param im: PIL Image object
    :param enc_format: The image format for displaying. If saved the image will have that extension.
    :return: base64 encoding
    """

    buff = BytesIO()
    im.save(buff, format=enc_format, **kwargs)
    encoded = base64.b64encode(buff.getvalue()).decode("utf-8")

    return encoded

html.Img(id="my-img",className="image", src="data:image/png;base64, " + pil_to_b64(pil_img))