Skip to content

Commit 36c2447

Browse files
authored
Merge pull request #34 from FoamyGuy/support_colorconverter
Allow usage of ColorConverter with Bitmap saving
2 parents 53b2b2a + c1df2a6 commit 36c2447

File tree

1 file changed

+41
-6
lines changed

1 file changed

+41
-6
lines changed

adafruit_bitmapsaver.py

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
import gc
3232
import struct
3333
import board
34-
from displayio import Bitmap, Palette, Display
34+
from displayio import Bitmap, Palette, Display, ColorConverter
3535

3636
try:
3737
from typing import Tuple, Optional, Union
@@ -81,11 +81,38 @@ def _rgb565_to_bgr_tuple(color: int) -> Tuple[int, int, int]:
8181
return blue, green, red
8282

8383

84+
def rgb565_to_rgb888(rgb565):
85+
"""
86+
Convert from an integer representing rgb565 color into an integer
87+
representing rgb888 color.
88+
:param rgb565: Color to convert
89+
:return int: rgb888 color value
90+
"""
91+
# Shift the red value to the right by 11 bits.
92+
red5 = rgb565 >> 11
93+
# Shift the green value to the right by 5 bits and extract the lower 6 bits.
94+
green6 = (rgb565 >> 5) & 0b111111
95+
# Extract the lower 5 bits for blue.
96+
blue5 = rgb565 & 0b11111
97+
98+
# Convert 5-bit red to 8-bit red.
99+
red8 = round(red5 / 31 * 255)
100+
# Convert 6-bit green to 8-bit green.
101+
green8 = round(green6 / 63 * 255)
102+
# Convert 5-bit blue to 8-bit blue.
103+
blue8 = round(blue5 / 31 * 255)
104+
105+
# Combine the RGB888 values into a single integer
106+
rgb888_value = (red8 << 16) | (green8 << 8) | blue8
107+
108+
return rgb888_value
109+
110+
84111
# pylint:disable=too-many-locals
85112
def _write_pixels(
86113
output_file: BufferedWriter,
87114
pixel_source: Union[Bitmap, Display],
88-
palette: Optional[Palette],
115+
palette: Optional[Union[Palette, ColorConverter]],
89116
) -> None:
90117
saving_bitmap = isinstance(pixel_source, Bitmap)
91118
width, height = _rotated_height_and_width(pixel_source)
@@ -97,7 +124,13 @@ def _write_pixels(
97124
# pixel_source: Bitmap
98125
for x in range(width):
99126
pixel = pixel_source[x, y - 1]
100-
color = palette[pixel] # handled by save_pixel's guardians
127+
if isinstance(palette, Palette):
128+
color = palette[pixel] # handled by save_pixel's guardians
129+
elif isinstance(palette, ColorConverter):
130+
converted = palette.convert(pixel)
131+
converted_888 = rgb565_to_rgb888(converted)
132+
color = converted_888
133+
101134
for _ in range(3):
102135
row_buffer[buffer_index] = color & 0xFF
103136
color >>= 8
@@ -124,7 +157,7 @@ def _write_pixels(
124157
def save_pixels(
125158
file_or_filename: Union[str, BufferedWriter],
126159
pixel_source: Union[Display, Bitmap] = None,
127-
palette: Optional[Palette] = None,
160+
palette: Optional[Union[Palette, ColorConverter]] = None,
128161
) -> None:
129162
"""Save pixels to a 24 bit per pixel BMP file.
130163
If pixel_source if a displayio.Bitmap, save it's pixels through palette.
@@ -140,8 +173,10 @@ def save_pixels(
140173
pixel_source = board.DISPLAY
141174

142175
if isinstance(pixel_source, Bitmap):
143-
if not isinstance(palette, Palette):
144-
raise ValueError("Third argument must be a Palette for a Bitmap save")
176+
if not isinstance(palette, Palette) and not isinstance(palette, ColorConverter):
177+
raise ValueError(
178+
"Third argument must be a Palette or ColorConverter for a Bitmap save"
179+
)
145180
elif not isinstance(pixel_source, Display):
146181
raise ValueError("Second argument must be a Bitmap or Display")
147182
try:

0 commit comments

Comments
 (0)