Source code for openpyxl.drawing.image

# Copyright (c) 2010-2024 openpyxl

from io import BytesIO

try:
    from PIL import Image as PILImage
except ImportError:
    PILImage = False


def _import_image(img):
    if not PILImage:
        raise ImportError("You must install Pillow to fetch image objects")
    if not isinstance(img, PILImage.Image):
        img = PILImage.open(img)
    return img


[docs] class Image: """Image in a spreadsheet""" _id = 1 _path = "/xl/media/image{0}.{1}" anchor = "A1" def __init__(self, img): self.ref = img mark_to_close = isinstance(img, str) image = _import_image(img) self.width, self.height = image.size try: self.format = image.format.lower() except AttributeError: self.format = "png" if hasattr(img, "read"): img.seek(0) self._cached_data = img.read() if mark_to_close: image.close() def _data(self): if hasattr(self, "_cached_data"): return self._cached_data ref = self.ref if isinstance(ref, str): img = _import_image(ref) elif hasattr(ref, "filename") and ref.filename: img = _import_image(ref.filename) elif hasattr(ref, "read"): if getattr(ref, "closed", False): raise ValueError("Image file handle is closed and no cache available.") else: ref.seek(0) ref = BytesIO(ref.read()) img = _import_image(ref) else: img = _import_image(ref) if self.format in ["gif", "jpeg", "png"]: if getattr(img, "fp", None) and not img.fp.closed: img.fp.seek(0) fp = img.fp else: tmp = BytesIO() img.save(tmp, format=self.format) tmp.seek(0) fp = tmp else: fp = BytesIO() img.save(fp, format="png") fp.seek(0) data = fp.read() try: fp.close() except OSError: pass return data @property def path(self): return self._path.format(self._id, self.format)