Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

This needs an update #221

Open
github-actions bot opened this issue Aug 18, 2024 · 0 comments
Open

This needs an update #221

github-actions bot opened this issue Aug 18, 2024 · 0 comments
Assignees
Labels

Comments

@github-actions
Copy link

if not hasattr(self.gainmap, "encoderinfo"):

self.gainmap.encoderinfo = {}

https://github.com/cmahnke/christianmahnke/blob/05320b425ec41ff2b4e63dedd09538f5e11fa62e/Source Files/Mocks/hdr-iiif/scripts/manipulator_uhdr_pillow.py#L181

import tempfile

from iiif.manipulator import IIIFManipulator

from PIL import Image

from UhdrImagePlugin import check_uhdr
from ImageXmp import ImageXmp, _get_size


class IIIFManipulatorUHDR(IIIFManipulator):

    tmpdir = "/tmp"
    filecmd = None
    pnmdir = None

    def __init__(self, **kwargs):
        super(IIIFManipulatorUHDR, self).__init__(**kwargs)
        self.compliance_level = 2
        self.image = None
        self.outtmp = None
        self.work_image_initialized = False
        self.height = 0
        self.width = 0
        self.gainmap = None
        self.icc = None
        self.xmps = []
        self.mime_type = None
        self.exif = None

    def set_max_image_pixels(self, pixels):
        # Default is alway UHDR max
        if pixels < 32768 * 32768:
            pixels = 32768 * 32768
        Image.MAX_IMAGE_PIXELS = pixels

    # Loads the image
    def do_first(self):
        self.image = Image.open(self.srcfile)
        self.icc = self.image.info.get("icc_profile")
        self.xmps.append(self.image.get_xmp())
        self.exif = self.image.getexif()
        self.logger.debug("Loaded image size %s", self.image.size)

        if self.image.n_frames > 1:
            self.image.seek(1)
            self.gainmap = self.image.copy()
            self.xmps.append(self.image.get_xmp())
        else:
            # pass
            raise IndexError(f"Couldn't find gain map in {self.srcfile}")
        self.image.seek(0)
        self.width, self.height = self.image.size

    def do_region(self, x, y, w, h):
        if x is None:
            self.logger.debug("Ignore crop without args")
        else:
            self.image, self.gainmap = self._crop((x, y, x + w, y + h))
            self.work_image_initialized = True
            self.width = w
            self.height = h

    def do_size(self, w, h):
        if w is None:
            self.logger.debug("Ignore scale without args")
        else:
            self.logger.debug("Scaling to %dx%d", w, h)
            self.image, self.gainmap = self._resize((w, h))
            self.width = w
            self.height = h

    def do_rotation(self, mirror, rot):
        if not mirror and rot == 0.0:
            self.logger.debug("Ignoring rotation nop")
            return
        raise NotImplementedError(f"Rotation not implemented for { mirror}, {rot}!")

    def do_quality(self, quality):
        if quality in ("grey", "gray", "bitonal"):
            raise NotImplementedError("Bitonal and grey images not implemented!")
        self.logger.debug("Ignoring quality '%s'", quality)

    # This is the save method
    # pylint: disable=redefined-builtin
    def do_format(self, format):
        if format != "jpg" or format is None:
            raise NotImplementedError(f"Unsuported format: {format}!")
        if self.outfile is None:
            # Create temp
            temp_file = tempfile.NamedTemporaryFile(delete=False)
            self.outfile = temp_file.name
        self.mime_type = "image/jpeg"
        self._save(self.outfile)

    def _crop(self, dim):
        self.logger.debug("Cropping from %s to %s", self.image.size, dim)
        x, y, w, h = dim
        self.image.seek(0)
        primary_dim = self.image.size
        primary = self.image.crop((x, y, w, h))

        self.image.seek(1)
        gainmap_size = self.image.size
        w_multiplier = gainmap_size[0] / primary_dim[0]
        h_multiplier = gainmap_size[1] / primary_dim[1]
        gainmap_dim = (
            x * w_multiplier,
            y * h_multiplier,
            w * w_multiplier,
            h * h_multiplier,
        )
        self.logger.debug("Cropping gainmap to %s", gainmap_dim)
        gainmap = self.image.crop(gainmap_dim)
        self.logger.debug(
            "Primary size %s, gainmap size %s, multipliers w: %s, h: %s",
            primary_dim,
            gainmap_size,
            w_multiplier,
            h_multiplier,
        )

        return (primary, gainmap)

    def _resize(self, dim):
        self.logger.debug("Resize from %s to %s", self.image.size, dim)
        self.image.seek(0)
        primary_dim = self.image.size
        primary = self.image.resize(dim)

        def gainmap_scale(new_dim, gainmap_dim, primary_dim):
            w_multiplier = gainmap_dim[0] / primary_dim[0]
            h_multiplier = gainmap_dim[1] / primary_dim[1]
            new_w = int(new_dim[0] * w_multiplier)
            if new_w < 2:
                new_w = 2
            new_h = int(new_dim[1] * h_multiplier)
            if new_h < 2:
                new_h = 2
            self.logger.debug(
                "Primary size %s, gainmap size %s, expected size %s, multipliers w: %s, h: %s, calculated w: %s h %s",
                primary_dim,
                gainmap_dim,
                new_dim,
                w_multiplier,
                h_multiplier,
                new_w,
                new_h,
            )
            return (new_w, new_h)

        if not self.work_image_initialized:
            self.image.seek(1)
            gainmap_dim = self.image.size
            new_dim = gainmap_scale(dim, gainmap_dim, primary_dim)
            # w_multiplier = gainmap_size[0] / primary_dim[0]
            # h_multiplier = gainmap_size[1] / primary_dim[1]
            # gainmap_dim = (int(dim[0] * w_multiplier), int(dim[1] * h_multiplier))
            gainmap = self.image.resize(new_dim)
        else:
            gainmap_dim = self.gainmap.size
            # w_multiplier = gainmap_size[0] / primary_dim[0]
            # h_multiplier = gainmap_size[1] / primary_dim[1]
            # gainmap_dim = (int(dim[0] * w_multiplier), int(dim[1] * h_multiplier))
            new_dim = gainmap_scale(dim, gainmap_dim, primary_dim)
            gainmap = self.gainmap.resize(new_dim)
        self.logger.debug("Resized gainmap from %s to %s", gainmap_dim, new_dim)

        return (primary, gainmap)

    def _save(self, filename):
        self.image.seek(0)
        self.image.info["icc_profile"] = self.icc

        # if not hasattr(self.image, "encoderinfo"):
        #    self.image.encoderinfo = {}
        gainmap_size = _get_size(self.gainmap)
        updated_xmp = ImageXmp.update_gainmap_xmp(self.xmps[0].tostring(), gainmap_size)
        # self.logger.debug(f"Updated primary XMP to {updated_xmp.tostring()}")
        self.xmps[0] = ImageXmp(updated_xmp)
        # TODO: This needs an update
        self.logger.debug("Setting primary XMP to %s", self.xmps[0].tostring())
        self.image.encoderinfo["xmp"] = self.xmps[0].tostring()

        # self.image.seek(1)
        # if not hasattr(self.gainmap, "encoderinfo"):
        #    self.gainmap.encoderinfo = {}
        self.logger.debug("setting gainmap XMP to %s", self.xmps[1].tostring())
        self.gainmap.encoderinfo["xmp"] = self.xmps[1].tostring()
        self.image.save(
            filename,
            save_all=True,
            append_images=[self.gainmap],
            exif=self.exif,
            icc_profile=self.icc,
        )
        if not check_uhdr(filename):
            self.logger.warning("%s is not a valid UHDR file", filename)

    def cleanup(self):
        with self.image as i:
            i.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant