From: Melissa LeBlanc-Williams Date: Fri, 12 Jun 2020 17:38:03 +0000 (-0700) Subject: Added OnDiskBitmap functionality X-Git-Tag: 0.3.0^2~2 X-Git-Url: https://git.ayoreis.com/hackapet/Adafruit_Blinka_Displayio.git/commitdiff_plain/7767c66c2b14bb9d2e5f4eb11d944674b2a78b7f Added OnDiskBitmap functionality --- diff --git a/displayio/colorconverter.py b/displayio/colorconverter.py index ead3f34..a93da2d 100644 --- a/displayio/colorconverter.py +++ b/displayio/colorconverter.py @@ -51,11 +51,12 @@ class ColorConverter: """ self._dither = dither self._depth = 16 + self._rgba = False # pylint: disable=no-self-use def _compute_rgb565(self, color): self._depth = 16 - return (color >> 19) << 11 | ((color >> 10) & 0x3F) << 5 | (color >> 3) & 0x1F + return (color[0] & 0xF8) << 8 | (color[1] & 0xFC) << 3 | color[2] >> 3 def _compute_luma(self, color): red = color >> 16 @@ -104,8 +105,20 @@ class ColorConverter: def convert(self, color): "Converts the given rgb888 color to RGB565" + if isinstance(color, int): + color = ((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF, 255) + elif isinstance(color, tuple): + if len(color) == 3: + color = (color[0], color[1], color[2], 255) + elif len(color) != 4: + raise ValueError("Color must be a 3 or 4 value tuple") + else: + raise ValueError("Color must be an integer or 3 or 4 value tuple") + if self._dither: return color # To Do: return a dithered color + if self._rgba: + return color return self._compute_rgb565(color) # pylint: enable=no-self-use @@ -122,3 +135,16 @@ class ColorConverter: if not isinstance(value, bool): raise ValueError("Value should be boolean") self._dither = value + + @property + def rgba(self): + """When true the color converter returns a 4-value + RGBA tuple rather than an integer + """ + return self._rgba + + @rgba.setter + def rgba(self, value): + if not isinstance(value, bool): + raise ValueError("Value should be boolean") + self._rgba = value diff --git a/displayio/ondiskbitmap.py b/displayio/ondiskbitmap.py index 3a08ab3..5e1de46 100644 --- a/displayio/ondiskbitmap.py +++ b/displayio/ondiskbitmap.py @@ -50,7 +50,7 @@ class OnDiskBitmap: image is visible.""" def __init__(self, file): - self._image = Image.open(file) + self._image = Image.open(file).convert("RGBA") @property def width(self): @@ -61,3 +61,19 @@ class OnDiskBitmap: def height(self): """Height of the bitmap. (read only)""" return self._image.height + + def __getitem__(self, index): + """ + Returns the value at the given index. The index can either be + an x,y tuple or an int equal to `y * width + x`. + """ + if isinstance(index, (tuple, list)): + x = index[0] + y = index[1] + elif isinstance(index, int): + x = index % self._image._width + y = index // self._image._width + if not 0 <= x < self._image.width or not 0 <= y < self._image.height: + return 0 + + return self._image.getpixel((x, y)) diff --git a/displayio/tilegrid.py b/displayio/tilegrid.py index 76d3b2c..2536af5 100644 --- a/displayio/tilegrid.py +++ b/displayio/tilegrid.py @@ -82,9 +82,13 @@ class TileGrid: bitmap_width = bitmap.width bitmap_height = bitmap.height - if not isinstance(pixel_shader, (ColorConverter, Palette)): + if pixel_shader is not None and not isinstance( + pixel_shader, (ColorConverter, Palette) + ): raise ValueError("Unsupported Pixel Shader type") self._pixel_shader = pixel_shader + if isinstance(self._pixel_shader, ColorConverter): + self._pixel_shader.rgba = True self._hidden = False self._x = x self._y = y @@ -93,6 +97,8 @@ class TileGrid: self._transpose_xy = False self._flip_x = False self._flip_y = False + self._top_left_x = 0 + self._top_left_y = 0 if tile_width is None: tile_width = bitmap_width if tile_height is None: @@ -184,6 +190,13 @@ class TileGrid: self._current_area.y1, ) + def _shade(self, pixel_value): + if isinstance(self._pixel_shader, Palette): + return self._pixel_shader[pixel_value]["rgba"] + if isinstance(self._pixel_shader, ColorConverter): + return self._pixel_shader.convert(pixel_value) + return pixel_value + # pylint: disable=too-many-locals def _fill_area(self, buffer): """Draw onto the image""" @@ -211,11 +224,8 @@ class TileGrid: image_y = (tile_y * self._tile_height) + pixel_y bitmap_x = (tile_index_x * self._tile_width) + pixel_x bitmap_y = (tile_index_y * self._tile_height) + pixel_y - pixel_color = self._pixel_shader[ - self._bitmap[bitmap_x, bitmap_y] - ] - # if not pixel_color["transparent"]: - image.putpixel((image_x, image_y), pixel_color["rgba"]) + pixel_color = self._shade(self._bitmap[bitmap_x, bitmap_y]) + image.putpixel((image_x, image_y), pixel_color) if self._absolute_transform is not None: if self._absolute_transform.scale > 1: