Convert image bytes to base64 in pyscript's render_image (#1020)

* Convert bytes to b64 if needed

* Move test and check for pattern
This commit is contained in:
Fábio Rosado
2022-12-05 21:37:03 +00:00
committed by GitHub
parent e284da7c09
commit c61d4191c3
2 changed files with 49 additions and 0 deletions

View File

@@ -3,6 +3,7 @@ import asyncio
import base64
import html
import io
import re
import time
from collections import namedtuple
from textwrap import dedent
@@ -33,6 +34,20 @@ MIME_METHODS = {
def render_image(mime, value, meta):
# If the image value is using bytes we should convert it to base64
# otherwise it will return raw bytes and the browser will not be able to
# render it.
if isinstance(value, bytes):
value = base64.b64encode(value).decode("utf-8")
# This is the pattern of base64 strings
base64_pattern = re.compile(
r"^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$"
)
# If value doesn't match the base64 pattern we should encode it to base64
if len(value) > 0 and not base64_pattern.match(value):
value = base64.b64encode(value.encode("utf-8")).decode("utf-8")
data = f"data:{mime};charset=utf-8;base64,{value}"
attrs = " ".join(['{k}="{v}"' for k, v in meta.items()])
return f'<img src="{data}" {attrs}</img>'

View File

@@ -1,6 +1,10 @@
import base64
import html
import io
import re
from PIL import Image
from .support import PyScriptTest
@@ -336,3 +340,33 @@ class TestOutput(PyScriptTest):
console_text = self.console.all.lines
assert console_text.index("1print") == (console_text.index("2print") - 1)
assert console_text.index("1console") == (console_text.index("2console") - 1)
def test_image_renders_correctly(self):
"""This is just a sanity check to make sure that images are rendered correctly."""
buffer = io.BytesIO()
img = Image.new("RGB", (4, 4), color=(0, 0, 0))
img.save(buffer, format="PNG")
b64_img = base64.b64encode(buffer.getvalue()).decode("utf-8")
expected_img_src = f"data:image/png;charset=utf-8;base64,{b64_img}"
self.pyscript_run(
"""
<py-config>
packages = ["pillow"]
</py-config>
<div id="img-target" />
<py-script>
from PIL import Image
img = Image.new("RGB", (4, 4), color=(0, 0, 0))
display(img, target='img-target', append=False)
</py-script>
"""
)
# TODO: This seems to be a py-script tag, should it?
rendered_img_src = self.page.locator("#py-internal-0 > img").get_attribute(
"src"
)
assert rendered_img_src == expected_img_src