def extract_image_primary_secondary_colors(self, logo, white_threshold=225, mitigate=175):
        """
        Identifies dominant colors

        First resizes the original image to improve performance, then discards
        transparent colors and white-ish colors, then calls the averaging
        method twice to evaluate both primary and secondary colors.

        :param logo: logo to process
        :param white_threshold: arbitrary value defining the maximum value a color can reach
        :param mitigate: arbitrary value defining the maximum value a band can reach

        :return colors: hex values of primary and secondary colors
        """
        if not logo:
            return False, False
        # The "===" gives different base64 encoding a correct padding
        logo += b'===' if type(logo) == bytes else '==='
        try:
            # Catches exceptions caused by logo not being an image
            image = tools.image_fix_orientation(tools.base64_to_image(logo))
        except Exception:
            return False, False

        base_w, base_h = image.size
        w = int(50 * base_w / base_h)
        h = 50

        # Converts to RGBA (if already RGBA, this is a noop)
        image_converted = image.convert('RGBA')
        image_resized = image_converted.resize((w, h), resample=Image.NEAREST)

        colors = []
        for color in image_resized.getcolors(w * h):
            if not(color[1][0] > white_threshold and
                   color[1][1] > white_threshold and
                   color[1][2] > white_threshold) and color[1][3] > 0:
                colors.append(color)

        if not colors:  # May happen when the whole image is white
            return False, False
        primary, remaining = tools.average_dominant_color(colors, mitigate=mitigate)
        secondary = tools.average_dominant_color(remaining, mitigate=mitigate)[0] if remaining else primary

        # Lightness and saturation are calculated here.
        # - If both colors have a similar lightness, the most colorful becomes primary
        # - When the difference in lightness is too great, the brightest color becomes primary
        l_primary = tools.get_lightness(primary)
        l_secondary = tools.get_lightness(secondary)
        if (l_primary < 0.2 and l_secondary < 0.2) or (l_primary >= 0.2 and l_secondary >= 0.2):
            s_primary = tools.get_saturation(primary)
            s_secondary = tools.get_saturation(secondary)
            if s_primary < s_secondary:
                primary, secondary = secondary, primary
        elif l_secondary > l_primary:
            primary, secondary = secondary, primary

        return tools.rgb_to_hex(primary), tools.rgb_to_hex(secondary)
Beispiel #2
0
 def _orientation_test(self, orientation, colors, size, expected):
     # Generate the test image based on orientation and order of colors.
     image = self._get_exif_colored_square(orientation, colors, size)
     # The image is read again now that it has orientation added.
     fixed_image = tools.image_fix_orientation(img_open(image))
     # Ensure colors are in the right order (blue, yellow, green, pink).
     self._assertAlmostEqualSequence(fixed_image.getpixel((0, 0)),
                                     expected[0])  # top/left
     self._assertAlmostEqualSequence(fixed_image.getpixel((size - 1, 0)),
                                     expected[1])  # top/right
     self._assertAlmostEqualSequence(fixed_image.getpixel((0, size - 1)),
                                     expected[2])  # bottom/left
     self._assertAlmostEqualSequence(
         fixed_image.getpixel((size - 1, size - 1)),
         expected[3])  # bottom/right
Beispiel #3
0
 def test_03_image_fix_orientation_exif(self):
     """Test that a jpg image with exif orientation tag gets rotated"""
     image = img_open(self.img_exif_jpg)
     self.assertEqual(image.size, (6, 3))
     image = tools.image_fix_orientation(image)
     self.assertEqual(image.size, (3, 6))