2222ENCODING_BWR = np .array ([[0 , 0 ], [0 , 1 ], [1 , 1 ]],
2323 dtype = np .uint8 )
2424
25- # 7-color (black, white, green, blue, red , yellow, orange) as an 8-bit RGB
25+ # 7-color (black, white, red, green, blue , yellow, orange) as an 8-bit RGB
2626# array.
27- PALETTE_7COLOR = np .array ([[16 , 16 , 16 ], [239 , 239 , 239 ], [27 , 120 , 27 ],
28- [54 , 43 , 162 ], [180 , 21 , 21 ], [224 , 212 , 13 ],
27+ PALETTE_7COLOR = np .array ([[16 , 16 , 16 ], [239 , 239 , 239 ], [180 , 21 , 21 ],
28+ [27 , 120 , 27 ], [54 , 43 , 162 ], [224 , 212 , 13 ],
2929 [193 , 103 , 13 ]],
3030 dtype = np .uint8 )
3131
32- # 7-color (black, white, green, blue, red , yellow, orange) as a 4-bit index
32+ # 7-color (black, white, red, green, blue , yellow, orange) as a 4-bit index
3333# array.
34- ENCODING_7COLOR = np .array ([[0 , 0 , 0 , 0 ], [0 , 0 , 0 , 1 ], [0 , 0 , 1 , 0 ],
35- [0 , 0 , 1 , 1 ], [0 , 1 , 0 , 0 ], [0 , 1 , 0 , 1 ],
34+ ENCODING_7COLOR = np .array ([[0 , 0 , 0 , 0 ], [0 , 0 , 0 , 1 ], [0 , 1 , 0 , 0 ],
35+ [0 , 0 , 1 , 0 ], [0 , 0 , 1 , 1 ], [0 , 1 , 0 , 1 ],
3636 [0 , 1 , 1 , 0 ]],
3737 dtype = np .uint8 )
3838
@@ -62,28 +62,37 @@ def _dither(image, palette):
6262 """Dithers the image using the Floyd-Steinberg algorithm."""
6363
6464 # Call the C extension to iterate over all image pixels efficiently.
65- pixels = np .array (image .convert ('RGB' ))
66- dither (pixels , palette )
65+ with image .convert ('RGB' ) as rgb_image :
66+ pixels = np .array (rgb_image )
67+ dither (pixels , palette )
6768
68- return Image .fromarray (pixels )
69+ return Image .fromarray (pixels )
6970
7071
7172def _color_indices (image , variant ):
7273 """Maps each image pixel to the index of the closest palette color."""
7374
74- # Apply dithering unless the image is already quantized.
75- palette = epd_palette (variant )
76- if image .mode not in ('1' , 'L' , 'P' ):
75+ # Figure out if the image is already quantized.
76+ is_quantized = image .mode in ('1' , 'L' , 'P' )
77+
78+ # Apply dithering, if needed.
79+ palette = _epd_palette (variant )
80+ if not is_quantized :
7781 image = _dither (image , palette )
7882
7983 # Map each pixel to the closest palette color.
80- pixels = np . array ( image .convert ('RGB' )). reshape ( - 1 , 3 )
81- indices = vector_quantize ( pixels , palette )
84+ with image .convert ('RGB' ) as rgb_image :
85+ pixels = np . array ( rgb_image ). reshape ( - 1 , 3 )
8286
83- return indices
87+ # Match against the BWR palette for quantized images. This requires
88+ # other palettes to start with the BWR color sequence in order.
89+ match_palette = PALETTE_BWR if is_quantized else palette
90+
91+ # Quantize the image.
92+ return vector_quantize (pixels , match_palette )
8493
8594
86- def epd_palette (variant ):
95+ def _epd_palette (variant ):
8796 """Returns the RGB palette used by the display."""
8897
8998 if variant == 'bwr' :
@@ -94,7 +103,7 @@ def epd_palette(variant):
94103 raise ValueError ('Unsupported display variant: %s' % variant )
95104
96105
97- def epd_encoding (variant ):
106+ def _epd_encoding (variant ):
98107 """Returns the color encoding used to send data to the display."""
99108
100109 if variant == 'bwr' :
@@ -109,7 +118,7 @@ def to_epd_image(image, variant):
109118 """Converts the image's colors to the closest palette color."""
110119
111120 indices = _color_indices (image , variant )
112- palette = epd_palette (variant )
121+ palette = _epd_palette (variant )
113122 epd_image_data = palette [indices .reshape ((image .height , image .width ))]
114123
115124 return Image .fromarray (epd_image_data )
@@ -119,7 +128,7 @@ def to_epd_bytes(image, variant):
119128 """Converts the image to the closest 2-bit palette color bytes."""
120129
121130 indices = _color_indices (image , variant )
122- encoding = epd_encoding (variant )
131+ encoding = _epd_encoding (variant )
123132 epd_image_data = encoding [indices .reshape ((image .height * image .width ))]
124133
125134 return np .packbits (epd_image_data )
0 commit comments