diff --git a/inky/inky_e673.py b/inky/inky_e673.py index 86e91b3..4d9c580 100644 --- a/inky/inky_e673.py +++ b/inky/inky_e673.py @@ -79,8 +79,8 @@ class Inky: WHITE = 1 YELLOW = 2 RED = 3 - BLUE = 5 - GREEN = 6 + BLUE = 4 + GREEN = 5 WIDTH = 0 HEIGHT = 0 @@ -308,16 +308,34 @@ def set_image(self, image, saturation=0.5): """ if not image.size == (self.width, self.height): raise ValueError(f"Image must be ({self.width}x{self.height}) pixels!") - if not image.mode == "P": + + dither = Image.Dither.FLOYDSTEINBERG + + # Image size doesn't matter since it's just the palette we're using + palette_image = Image.new("P", (1, 1)) + + if image.mode == "P": + # Create a pure colour palette from DESATURATED_PALETTE + palette = numpy.array(DESATURATED_PALETTE, dtype=numpy.uint8).flatten().tobytes() + palette_image.putpalette(palette) + + # Assume that palette mode images with an unset palette use the + # default colour order and "DESATURATED_PALETTE" pure colours + if not image.palette.colors: + image.putpalette(palette) + + # Assume that palette mode images with exactly six colours use + # all the correct colours, but not exactly in the right order. + if len(image.palette.colors) == 6: + dither = Image.Dither.NONE + else: + # All other image should be quantized and dithered palette = self._palette_blend(saturation) - # Image size doesn't matter since it's just the palette we're using - palette_image = Image.new("P", (1, 1)) - # Set our 6 colour palette and zero out the remaining colours - palette_image.putpalette(palette + [0, 0, 0] * 248) - # Force source image data to be loaded for `.im` to work - image.load() - image = image.im.convert("P", True, palette_image.im) + palette_image.putpalette(palette) + + image = image.convert("RGB").quantize(6, palette=palette_image, dither=dither) + # Remap our sequential palette colours to display native (missing colour 4) remap = numpy.array([0, 1, 2, 3, 5, 6]) self.buf = remap[numpy.array(image, dtype=numpy.uint8).reshape((self.rows, self.cols))] diff --git a/inky/inky_el133uf1.py b/inky/inky_el133uf1.py index b35506f..fbe2353 100644 --- a/inky/inky_el133uf1.py +++ b/inky/inky_el133uf1.py @@ -97,8 +97,8 @@ class Inky: WHITE = 1 YELLOW = 2 RED = 3 - BLUE = 5 - GREEN = 6 + BLUE = 4 + GREEN = 5 WIDTH = 0 HEIGHT = 0 @@ -326,22 +326,41 @@ def set_border(self, colour): def set_image(self, image, saturation=0.5): """Copy an image to the display. - :param image: PIL image to copy, must be 1600x1200 + + :param image: PIL image to copy, must be 800x480 :param saturation: Saturation for quantization palette - higher value results in a more saturated image + """ if not image.size == (self.width, self.height): raise ValueError(f"Image must be ({self.width}x{self.height}) pixels!") - if not image.mode == "P": + dither = Image.Dither.FLOYDSTEINBERG + + # Image size doesn't matter since it's just the palette we're using + palette_image = Image.new("P", (1, 1)) + + if image.mode == "P": + # Create a pure colour palette from DESATURATED_PALETTE + palette = numpy.array(DESATURATED_PALETTE, dtype=numpy.uint8).flatten().tobytes() + palette_image.putpalette(palette) + + # Assume that palette mode images with an unset palette use the + # default colour order and "DESATURATED_PALETTE" pure colours + if not image.palette.colors: + image.putpalette(palette) + + # Assume that palette mode images with exactly six colours use + # all the correct colours, but not exactly in the right order. + if len(image.palette.colors) == 6: + dither = Image.Dither.NONE + else: + # All other image should be quantized and dithered palette = self._palette_blend(saturation) - # Image size doesn't matter since it's just the palette we're using - palette_image = Image.new("P", (1, 1)) - # Set our 7 colour palette (+ clear) and zero out the remaining colours - palette_image.putpalette(palette + [0, 0, 0] * 250) - # Force source image data to be loaded for `.im` to work - image.load() - image = image.im.convert("P", True, palette_image.im) + palette_image.putpalette(palette) + + image = image.convert("RGB").quantize(6, palette=palette_image, dither=dither) + # Remap our sequential palette colours to display native (missing colour 4) remap = numpy.array([0, 1, 2, 3, 5, 6]) self.buf = remap[numpy.array(image, dtype=numpy.uint8).reshape((self.rows, self.cols))] diff --git a/tests/test_e673.py b/tests/test_e673.py new file mode 100644 index 0000000..0092fb6 --- /dev/null +++ b/tests/test_e673.py @@ -0,0 +1,13 @@ +def test_set_image_p256(GPIO, spidev): + from PIL import Image + + from inky import inky_e673 + + img = Image.new("P", (800, 480)) + + for x in range(256): + img.putpixel((x, x), (x, 0, 0)) + + inky = inky_e673.Inky() + + inky.set_image(img)