| | from io import BytesIO |
| | import base64 |
| | from .png import Writer, from_array |
| |
|
| | try: |
| | from PIL import Image |
| |
|
| | pil_imported = True |
| | except ImportError: |
| | pil_imported = False |
| |
|
| |
|
| | def image_array_to_data_uri(img, backend="pil", compression=4, ext="png"): |
| | """Converts a numpy array of uint8 into a base64 png or jpg string. |
| | |
| | Parameters |
| | ---------- |
| | img: ndarray of uint8 |
| | array image |
| | backend: str |
| | 'auto', 'pil' or 'pypng'. If 'auto', Pillow is used if installed, |
| | otherwise pypng. |
| | compression: int, between 0 and 9 |
| | compression level to be passed to the backend |
| | ext: str, 'png' or 'jpg' |
| | compression format used to generate b64 string |
| | """ |
| | |
| | if compression < 0 or compression > 9: |
| | raise ValueError("compression level must be between 0 and 9.") |
| | alpha = False |
| | if img.ndim == 2: |
| | mode = "L" |
| | elif img.ndim == 3 and img.shape[-1] == 3: |
| | mode = "RGB" |
| | elif img.ndim == 3 and img.shape[-1] == 4: |
| | mode = "RGBA" |
| | alpha = True |
| | else: |
| | raise ValueError("Invalid image shape") |
| | if backend == "auto": |
| | backend = "pil" if pil_imported else "pypng" |
| | if ext != "png" and backend != "pil": |
| | raise ValueError("jpg binary strings are only available with PIL backend") |
| |
|
| | if backend == "pypng": |
| | ndim = img.ndim |
| | sh = img.shape |
| | if ndim == 3: |
| | img = img.reshape((sh[0], sh[1] * sh[2])) |
| | w = Writer( |
| | sh[1], sh[0], greyscale=(ndim == 2), alpha=alpha, compression=compression |
| | ) |
| | img_png = from_array(img, mode=mode) |
| | prefix = "data:image/png;base64," |
| | with BytesIO() as stream: |
| | w.write(stream, img_png.rows) |
| | base64_string = prefix + base64.b64encode(stream.getvalue()).decode("utf-8") |
| | else: |
| | if not pil_imported: |
| | raise ImportError( |
| | "pillow needs to be installed to use `backend='pil'. Please" |
| | "install pillow or use `backend='pypng'." |
| | ) |
| | pil_img = Image.fromarray(img) |
| | if ext == "jpg" or ext == "jpeg": |
| | prefix = "data:image/jpeg;base64," |
| | ext = "jpeg" |
| | else: |
| | prefix = "data:image/png;base64," |
| | ext = "png" |
| | with BytesIO() as stream: |
| | pil_img.save(stream, format=ext, compress_level=compression) |
| | base64_string = prefix + base64.b64encode(stream.getvalue()).decode("utf-8") |
| | return base64_string |
| |
|