Skip to content

Commit

Permalink
Merge pull request #34 from FoamyGuy/support_colorconverter
Browse files Browse the repository at this point in the history
Allow usage of ColorConverter with Bitmap saving
  • Loading branch information
tannewt authored Feb 20, 2024
2 parents 53b2b2a + c1df2a6 commit 36c2447
Showing 1 changed file with 41 additions and 6 deletions.
47 changes: 41 additions & 6 deletions adafruit_bitmapsaver.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import gc
import struct
import board
from displayio import Bitmap, Palette, Display
from displayio import Bitmap, Palette, Display, ColorConverter

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


def rgb565_to_rgb888(rgb565):
"""
Convert from an integer representing rgb565 color into an integer
representing rgb888 color.
:param rgb565: Color to convert
:return int: rgb888 color value
"""
# Shift the red value to the right by 11 bits.
red5 = rgb565 >> 11
# Shift the green value to the right by 5 bits and extract the lower 6 bits.
green6 = (rgb565 >> 5) & 0b111111
# Extract the lower 5 bits for blue.
blue5 = rgb565 & 0b11111

# Convert 5-bit red to 8-bit red.
red8 = round(red5 / 31 * 255)
# Convert 6-bit green to 8-bit green.
green8 = round(green6 / 63 * 255)
# Convert 5-bit blue to 8-bit blue.
blue8 = round(blue5 / 31 * 255)

# Combine the RGB888 values into a single integer
rgb888_value = (red8 << 16) | (green8 << 8) | blue8

return rgb888_value


# pylint:disable=too-many-locals
def _write_pixels(
output_file: BufferedWriter,
pixel_source: Union[Bitmap, Display],
palette: Optional[Palette],
palette: Optional[Union[Palette, ColorConverter]],
) -> None:
saving_bitmap = isinstance(pixel_source, Bitmap)
width, height = _rotated_height_and_width(pixel_source)
Expand All @@ -97,7 +124,13 @@ def _write_pixels(
# pixel_source: Bitmap
for x in range(width):
pixel = pixel_source[x, y - 1]
color = palette[pixel] # handled by save_pixel's guardians
if isinstance(palette, Palette):
color = palette[pixel] # handled by save_pixel's guardians
elif isinstance(palette, ColorConverter):
converted = palette.convert(pixel)
converted_888 = rgb565_to_rgb888(converted)
color = converted_888

for _ in range(3):
row_buffer[buffer_index] = color & 0xFF
color >>= 8
Expand All @@ -124,7 +157,7 @@ def _write_pixels(
def save_pixels(
file_or_filename: Union[str, BufferedWriter],
pixel_source: Union[Display, Bitmap] = None,
palette: Optional[Palette] = None,
palette: Optional[Union[Palette, ColorConverter]] = None,
) -> None:
"""Save pixels to a 24 bit per pixel BMP file.
If pixel_source if a displayio.Bitmap, save it's pixels through palette.
Expand All @@ -140,8 +173,10 @@ def save_pixels(
pixel_source = board.DISPLAY

if isinstance(pixel_source, Bitmap):
if not isinstance(palette, Palette):
raise ValueError("Third argument must be a Palette for a Bitmap save")
if not isinstance(palette, Palette) and not isinstance(palette, ColorConverter):
raise ValueError(
"Third argument must be a Palette or ColorConverter for a Bitmap save"
)
elif not isinstance(pixel_source, Display):
raise ValueError("Second argument must be a Bitmap or Display")
try:
Expand Down

0 comments on commit 36c2447

Please sign in to comment.