Exemplo n.º 1
0
    def add_to_image(self, im: pyvips.Image) -> pyvips.Image:
        """Add watermark to supplied image."""
        LOG.info("Adding watermark '%s'", self.text)
        text = pyvips.Image.text(
            self.text, width=im.width, dpi=300, font=f"{self.font}"
        )
        text = text.rotate(self.rotate)
        text = (text * self.opacity).cast("uchar")
        text = text.embed(
            self.x_margin,
            (im.height - text.height) - self.y_margin,
            im.width,
            im.height,
        )

        if self.replicate:
            text = text.replicate(
                1 + im.width / text.width, 1 + im.height / text.height
            )
            text = text.crop(0, 0, im.width, im.height)

        # we want to blend into the visible part of the image and leave any alpha
        # channels untouched ... we need to split im into two parts
        # guess how many bands from the start of im contain visible colour information
        if im.hasalpha():
            alpha = im.extract_band(im.bands - 1)
            im = im.extract_band(0, n=im.bands - 1)
        else:
            alpha = None

        if im.bands == 4:
            # cmyk
            text_color: Any = list(rgb_to_cmyk(self.fg_color))
        elif im.bands == 3:
            # rgb
            text_color = list(self.fg_color)
        else:
            # mono
            text_color = rgb_to_grayscale(self.fg_color)
        LOG.info("Watermark fg_color: %s (original: %s)", text_color, self.fg_color)
        im = text.ifthenelse(text_color, im, blend=True)

        # reattach alpha
        if alpha:
            im = im.bandjoin(alpha)
        return im
Exemplo n.º 2
0
    def add(self, im: pyvips.Image) -> pyvips.Image:
        """Use method which finds complementary color.

        Returns image
        """
        text = pyvips.Image.text(
            self.text, width=im.width, dpi=300, font=f"{self.font}"
        )
        text = text.rotate(self.rotate)

        # the position of the overlay in the image
        margin = 25
        position = self.position

        if position == "top-left":
            x_pos = margin
            y_pos = margin
        elif position == "top-right":
            x_pos = im.width - text.width - margin
            y_pos = margin
        elif position == "bottom-right":
            x_pos = im.width - text.width - margin
            y_pos = im.height - text.height - margin
        elif position == "bottom-left":
            x_pos = margin
            y_pos = im.height - text.height - margin
        else:
            print(f"Incorrect watermark position: {position}")
            sys.exit(1)

        # find the non-alpha image bands
        if im.hasalpha():
            no_alpha = im.extract_band(0, n=im.bands - 1)
        else:
            no_alpha = im

        # the pixels we will render the overlay on top of
        bg = no_alpha.crop(x_pos, y_pos, text.width, text.height)

        # mask the background with the text, so all non-text areas become zero, and find
        # the zero-excluding average
        avg = avgze(text.ifthenelse(bg, 0))

        # for each band, find the opposing value
        mx = 255 if im.format == "uchar" else 65535
        text_colour = [oppose(avg[i], mx) for i in range(len(avg))]

        # make an overlay ... we put solid colour into the image and set a faded version
        # of the text mask as the alpha
        overlay = bg.new_from_image(text_colour)
        overlay = overlay.bandjoin((text * self.opacity).cast("uchar"))

        # and composite that on to the original image
        im = im.composite(overlay, "over", x=x_pos, y=y_pos)
        return im
Exemplo n.º 3
0
 def _extract_channels(im: VIPSImage, c: Optional[Union[int, List[int]]]) -> VIPSImage:
     if c is None or im.bands == len(c):
         return im
     elif type(c) is int or len(c) == 1:
         if len(c) == 1:
             c = c[0]
         return im.extract_band(c)
     else:
         channels = list(itemgetter(*c)(im))
         im = channels[0].bandjoin(channels[1:])
         return im