from typing import Union, BinaryIO
from ._helpers import read_word
from ._colorconverter import ColorConverter
+from ._colorspace import Colorspace
from ._palette import Palette
__version__ = "0.0.0+auto.0"
load times. These load times may result in frame tearing where only part of the image is
visible.
- It's easiest to use on a board with a built in display such as the `Hallowing M0 Express
- <https://www.adafruit.com/product/3900>`_.
-
.. code-block:: Python
import board
board.DISPLAY.auto_brightness = False
board.DISPLAY.brightness = 0
splash = displayio.Group()
- board.DISPLAY.show(splash)
+ board.DISPLAY.root_group = splash
odb = displayio.OnDiskBitmap(\'/sample.bmp\')
face = displayio.TileGrid(odb, pixel_shader=odb.pixel_shader)
self._width = read_word(bmp_header, 9)
self._height = read_word(bmp_header, 11)
- self._colorconverter = ColorConverter()
+ self._pixel_shader_base = ColorConverter(
+ input_colorspace=Colorspace.RGB888, dither=False
+ )
if bits_per_pixel == 16:
if header_size >= 56 or self._bitfield_compressed:
if number_of_colors == 0:
number_of_colors = 1 << bits_per_pixel
- palette = Palette(number_of_colors)
+ palette = Palette(number_of_colors, dither=False)
if number_of_colors > 1:
palette_size = number_of_colors * 4
raise ValueError("Unable to read color palette data")
for i in range(number_of_colors):
- palette[i] = palette_data[i]
+ palette._set_color(
+ i, palette_data[i]
+ ) # pylint: disable=protected-access
else:
- palette[0] = 0x000000
- palette[1] = 0xFFFFFF
- self._palette = palette
+ palette._set_color(0x000000, 0) # pylint: disable=protected-access
+ palette._set_color(0xFFFFFF, 1) # pylint: disable=protected-access
+ self._pixel_shader_base = palette
elif header_size not in (12, 40, 108, 124):
raise ValueError(
"Only Windows format, uncompressed BMP supported: "
return self._pixel_shader_base
- @property
- def _colorconverter(self) -> ColorConverter:
- return self._pixel_shader_base
-
- @_colorconverter.setter
- def _colorconverter(self, colorconverter: ColorConverter) -> None:
- self._pixel_shader_base = colorconverter
-
- @property
- def _palette(self) -> Palette:
- return self._pixel_shader_base
-
- @_palette.setter
- def _palette(self, palette: Palette) -> None:
- self._pixel_shader_base = palette
-
def _get_pixel(self, x: int, y: int) -> int:
if not (0 <= x < self.width and 0 <= y < self.height):
return 0
self._file.seek(location)
- pixel_data = memoryview(self._file.read(4)).cast(
- "I"
- ) # cast as unsigned 32-bit int
- pixel_data = pixel_data[0] # We only need a single 32-bit uint
- if bytes_per_pixel == 1:
- offset = (x % pixels_per_byte) * self._bits_per_pixel
- mask = (1 << self._bits_per_pixel) - 1
- return (pixel_data >> ((8 - self._bits_per_pixel) - offset)) & mask
- if bytes_per_pixel == 2:
- if self._g_bitmask == 0x07E0: # 565
- red = (pixel_data & self._r_bitmask) >> 11
- green = (pixel_data & self._g_bitmask) >> 5
- blue = pixel_data & self._b_bitmask
- else: # 555
- red = (pixel_data & self._r_bitmask) >> 10
- green = (pixel_data & self._g_bitmask) >> 4
- blue = pixel_data & self._b_bitmask
- return red << 19 | green << 10 | blue << 3
- if bytes_per_pixel == 4 and self._bitfield_compressed:
- return pixel_data & 0x00FFFFFF
- return pixel_data
+ pixel_data = self._file.read(bytes_per_pixel)
+ if len(pixel_data) == bytes_per_pixel:
+ if bytes_per_pixel == 1:
+ offset = (x % pixels_per_byte) * self._bits_per_pixel
+ mask = (1 << self._bits_per_pixel) - 1
+ return (pixel_data[0] >> ((8 - self._bits_per_pixel) - offset)) & mask
+ if bytes_per_pixel == 2:
+ pixel_data = pixel_data[0] | pixel_data[1] << 8
+ if self._g_bitmask == 0x07E0: # 565
+ red = (pixel_data & self._r_bitmask) >> 11
+ green = (pixel_data & self._g_bitmask) >> 5
+ blue = pixel_data & self._b_bitmask
+ else: # 555
+ red = (pixel_data & self._r_bitmask) >> 10
+ green = (pixel_data & self._g_bitmask) >> 4
+ blue = pixel_data & self._b_bitmask
+ return red << 19 | green << 10 | blue << 3
+ if bytes_per_pixel == 4 and self._bitfield_compressed:
+ return pixel_data[0] | pixel_data[1] << 8 | pixel_data[2] << 16
+ pixel = pixel_data[0] | pixel_data[1] << 8 | pixel_data[2] << 16
+ if bytes_per_pixel == 4:
+ pixel |= pixel_data[3] << 24
+ return pixel
+ return 0
def _finish_refresh(self) -> None:
pass