diff --git a/adafruit_bitmapsaver.py b/adafruit_bitmapsaver.py index 4b7d892..ce3b82e 100644 --- a/adafruit_bitmapsaver.py +++ b/adafruit_bitmapsaver.py @@ -8,7 +8,7 @@ ================================================================================ Save a displayio.Bitmap (and associated displayio.Palette) in a BMP file. -Make a screenshot (the contents of a displayio.Display) and save in a BMP file. +Make a screenshot (the contents of a busdisplay.BusDisplay) and save in a BMP file. * Author(s): Dave Astels, Matt Land @@ -31,11 +31,14 @@ import gc import struct import board -from displayio import Bitmap, Palette, Display, ColorConverter +from displayio import Bitmap, Palette, ColorConverter + try: from typing import Tuple, Optional, Union from io import BufferedWriter + from busdisplay import BusDisplay + from framebufferio import FramebufferDisplay except ImportError: pass @@ -67,9 +70,11 @@ def _bytes_per_row(source_width: int) -> int: return pixel_bytes + padding_bytes -def _rotated_height_and_width(pixel_source: Union[Bitmap, Display]) -> Tuple[int, int]: +def _rotated_height_and_width( + pixel_source: Union[Bitmap, BusDisplay, FramebufferDisplay] +) -> Tuple[int, int]: # flip axis if the display is rotated - if isinstance(pixel_source, Display) and (pixel_source.rotation % 180 != 0): + if hasattr(pixel_source, "rotation") and (pixel_source.rotation % 180 != 0): return pixel_source.height, pixel_source.width return pixel_source.width, pixel_source.height @@ -111,7 +116,7 @@ def rgb565_to_rgb888(rgb565): # pylint:disable=too-many-locals def _write_pixels( output_file: BufferedWriter, - pixel_source: Union[Bitmap, Display], + pixel_source: Union[Bitmap, BusDisplay, FramebufferDisplay], palette: Optional[Union[Palette, ColorConverter]], ) -> None: saving_bitmap = isinstance(pixel_source, Bitmap) @@ -136,7 +141,7 @@ def _write_pixels( color >>= 8 buffer_index += 1 else: - # pixel_source: Display + # pixel_source: display result_buffer = bytearray(2048) data = pixel_source.fill_row(y - 1, result_buffer) for i in range(width): @@ -156,15 +161,17 @@ def _write_pixels( def save_pixels( file_or_filename: Union[str, BufferedWriter], - pixel_source: Union[Display, Bitmap] = None, + pixel_source: Union[BusDisplay, FramebufferDisplay, Bitmap] = 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. - If it's a displayio.Display, a palette isn't required. + If it's a displayio display, a palette isn't required. To be supported, + a display must implement `busdisplay.BusDisplay.fill_row`. Known supported + display types are `busdisplay.BusDisplay` and `framebufferio.FramebufferDisplay`. :param file_or_filename: either the file to save to, or it's absolute name - :param pixel_source: the Bitmap or Display to save + :param pixel_source: the Bitmap or display to save :param palette: the Palette to use for looking up colors in the bitmap """ if not pixel_source: @@ -177,8 +184,8 @@ def save_pixels( 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") + elif not hasattr(pixel_source, "fill_row"): + raise ValueError("Second argument must be a Bitmap or supported display type") try: if isinstance(file_or_filename, str): output_file = open( # pylint: disable=consider-using-with diff --git a/docs/api.rst b/docs/api.rst index 1819110..92e264a 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1,8 +1,6 @@ -.. If you created a package, create one automodule per module in the package. - -.. If your library file(s) are nested in a directory (e.g. /adafruit_foo/foo.py) -.. use this format as the module name: "adafruit_foo.foo" +API Reference +############# .. automodule:: adafruit_bitmapsaver :members: diff --git a/docs/conf.py b/docs/conf.py index 0262580..fa91348 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -27,7 +27,14 @@ # Uncomment the below if you use native CircuitPython modules such as # digitalio, micropython and busio. List the modules you use. Without it, the # autodoc module docs will fail to generate with a warning. -autodoc_mock_imports = ["displayio", "digitalio", "busio", "board"] +autodoc_mock_imports = [ + "busdisplay", + "displayio", + "digitalio", + "busio", + "board", + "framebufferio", +] intersphinx_mapping = {