Example #1
0
    def _create_background_box(self, lines: int, y_offset: int) -> TileGrid:
        """Private Class function to create a background_box
        :param lines: int number of lines
        :param y_offset: int y pixel bottom coordinate for the background_box"""

        left = self._bounding_box[0]
        if self._background_tight:  # draw a tight bounding box
            box_width = self._bounding_box[2]
            box_height = self._bounding_box[3]
            x_box_offset = 0
            y_box_offset = self._bounding_box[1]

        else:  # draw a "loose" bounding box to include any ascenders/descenders.
            ascent, descent = self._ascent, self._descent

            if self._label_direction in ("UPR", "DWR", "TTB"):
                box_height = (self._bounding_box[3] + self._padding_top +
                              self._padding_bottom)
                x_box_offset = -self._padding_bottom
                box_width = ((ascent + descent) + int(
                    (lines - 1) * self._width * self._line_spacing) +
                             self._padding_left + self._padding_right)
            else:
                box_width = (self._bounding_box[2] + self._padding_left +
                             self._padding_right)
                x_box_offset = -self._padding_left
                box_height = ((ascent + descent) + int(
                    (lines - 1) * self._height * self._line_spacing) +
                              self._padding_top + self._padding_bottom)

            if self._base_alignment:
                y_box_offset = -ascent - self._padding_top
            else:
                y_box_offset = -ascent + y_offset - self._padding_top

        box_width = max(0, box_width)  # remove any negative values
        box_height = max(0, box_height)  # remove any negative values

        if self._label_direction == "UPR":
            movx = left + x_box_offset
            movy = -box_height - x_box_offset
        elif self._label_direction == "DWR":
            movx = left + x_box_offset
            movy = x_box_offset
        elif self._label_direction == "TTB":
            movx = left + x_box_offset
            movy = x_box_offset
        else:
            movx = left + x_box_offset
            movy = y_box_offset

        background_bitmap = Bitmap(box_width, box_height, 1)
        tile_grid = TileGrid(
            background_bitmap,
            pixel_shader=self._background_palette,
            x=movx,
            y=movy,
        )

        return tile_grid
Example #2
0
    def register_click(self, click_pt):
        click_cmp = self.pix_to_cmp(click_pt)
        rng_r = (self.cmp_bounds[0][1] - self.cmp_bounds[0][0]) / 2
        rng_c = (self.cmp_bounds[1][1] - self.cmp_bounds[1][0]) / 2

        max_x = (self.pix_sz[0] - 1) // 2
        max_y = (self.pix_sz[1] - 1) // 2

        new_start_cmp = Complex(click_cmp.r - rng_r / 2,
                                click_cmp.c - rng_c / 2)
        new_start_pix = self.cmp_to_pix(new_start_cmp)
        new_start_pix = (max(0, min(int(new_start_pix[0]), max_x)),
                         max(0, min(int(new_start_pix[1]), max_y)))
        new_start_cmp = self.pix_to_cmp(new_start_pix)

        self.cmp_bounds = ((new_start_cmp.r, new_start_cmp.r + rng_r),
                           (new_start_cmp.c, new_start_cmp.c + rng_c))
        self.current_col = 0

        new_bitmap = Bitmap(self.pix_sz[0], self.pix_sz[1],
                            self.color_mapper.num_colors)

        for x in range(self.pix_sz[0]):
            for y in range(self.pix_sz[1]):
                new_bitmap[x, y] = self.bitmap[x // 2 + new_start_pix[0],
                                               y // 2 + new_start_pix[1]]
        self.bitmap = new_bitmap
        self.first_render = False
 def _generate_bitmap(self, start_range, end_range):
     char_width, char_height = self.get_bounding_box()
     self._bitmap = Bitmap(char_width * (end_range - start_range + 1),
                           char_height, 2)
     for character in range(start_range, end_range + 1):
         ascii_char = chr(character)
         ascii_mask = self._font.getmask(ascii_char, mode="1")
         for y in range(char_height):
             for x in range(char_width):
                 color = ascii_mask.getpixel((x, y))
                 character_position = character - start_range
                 self._bitmap[character_position * char_width + x,
                              y] = (1 if color else 0)
Example #4
0
    def init_class(cls,
                   display=None,
                   max_scale=1.5,
                   max_icon_size=(80, 80),
                   max_color_depth=256):
        """
        Initializes the IconAnimated Class variables, including preallocating memory
        buffers for the icon zoom bitmap and icon zoom palette.

        .. Note::  The `init_class` class function must be called before instancing any
                IconAnimated widgets. Usage example:
                ``IconAnimated.init_class(display=board.DISPLAY, max_scale=1.5,
                max_icon_size=(80,80), max_color_depth=256)``

        :param displayio.Display display: The display where the icons will be displayed.
        :param float max_scale: The maximum zoom of the any of the icons, should be >= 1.0,
         (default: 1.5)
        :param max_icon_size: The maximum (x,y) pixel dimensions of any `IconAnimated` bitmap size
         that will be created (default: (80,80)).  Note: This is the original pixel size,
         before scaling
        :type max_icon_size: Tuple[int,int]
        :param int max_color_depth: The maximum color depth of any `IconAnimated`
         bitmap that will be created (default: 256)
        """
        if display is None:
            raise ValueError(
                "IconAninmated.init_class: Must provide display parameter for IconAnimated."
            )

        if (isinstance(max_icon_size, tuple)
                and len(max_icon_size) == 2  # validate max_icon_size input
                and isinstance(max_icon_size[0], int)
                and isinstance(max_icon_size[1], int)):
            pass
        else:
            raise ValueError(
                "IconAninmated.init_class: max_icon_size must be an (x,y) "
                "tuple of integer pixel sizes.")

        cls.display = display
        if max_scale < 1.0:
            print("Warning: IconAnimated.init_class - max_scale value was "
                  "constrained to minimum of 1.0")
        cls.max_scale = max(1.0, max_scale)
        cls.bitmap_buffer = Bitmap(
            round(cls.max_scale * max_icon_size[0]),
            round(cls.max_scale * max_icon_size[1]),
            max_color_depth + 1,
        )
        cls.palette_buffer = Palette(max_color_depth + 1)
Example #5
0
    def __init__(self,
                 color_mapper,
                 max_iter,
                 fractal=mandelbrot_fractal,
                 pix_sz=(320, 240),
                 cmp_bounds=None):
        self.color_mapper = color_mapper
        self.fractal_fn = fractal.fractal_fn

        if pix_sz[0] % 2 == 0:
            pix_sz = (pix_sz[0] - 1, pix_sz[1])
        if pix_sz[1] % 2 == 0:
            pix_sz = (pix_sz[0], pix_sz[1] - 1)
        self.pix_sz = pix_sz

        self.first_render = True
        raw_cmp_bounds = cmp_bounds if cmp_bounds is not None else fractal.starting_cmp_bounds
        self.cmp_bounds = match_cmp_bounds_with_aspect_ratio(
            raw_cmp_bounds, self.pix_sz)

        self.max_iter = max_iter
        self.current_col = 0
        self.bitmap = Bitmap(self.pix_sz[0], self.pix_sz[1],
                             color_mapper.num_colors)
storage.mount(vfs, "/sd")

WHITE = 0xFFFFFF
BLACK = 0x000000
RED = 0xFF0000
ORANGE = 0xFFA500
YELLOW = 0xFFFF00
GREEN = 0x00FF00
BLUE = 0x0000FF
PURPLE = 0x800080
PINK = 0xFFC0CB

colors = (BLACK, RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE, WHITE)

print("Building sample bitmap and palette")
bitmap = Bitmap(16, 16, 9)
palette = Palette(len(colors))
for i, c in enumerate(colors):
    palette[i] = c

for x in range(16):
    for y in range(16):
        if x == 0 or y == 0 or x == 15 or y == 15:
            bitmap[x, y] = 1
        elif x == y:
            bitmap[x, y] = 4
        elif x == 15 - y:
            bitmap[x, y] = 5
        else:
            bitmap[x, y] = 0
Example #7
0
width = display.width
height = display.height

# cam.test_pattern = OV7670_TEST_PATTERN_COLOR_BAR

bitmap = None
# Select the biggest size for which we can allocate a bitmap successfully, and
# which is not bigger than the display
for size in range(OV7670_SIZE_DIV1, OV7670_SIZE_DIV16 + 1):
    cam.size = size
    if cam.width > width:
        continue
    if cam.height > height:
        continue
    try:
        bitmap = Bitmap(cam.width, cam.height, 65535)
        break
    except MemoryError:
        continue

print(width, height, cam.width, cam.height)
if bitmap is None:
    raise SystemExit("Could not allocate a bitmap")

g = Group(scale=1, x=(width - cam.width) // 2, y=(height - cam.height) // 2)
tg = TileGrid(
    bitmap,
    pixel_shader=ColorConverter(input_colorspace=Colorspace.RGB565_SWAPPED))
g.append(tg)
display.show(g)
Example #8
0
    def _blit(
        self,
        bitmap: displayio.Bitmap,  # target bitmap
        x: int,  # target x upper left corner
        y: int,  # target y upper left corner
        source_bitmap: displayio.Bitmap,  # source bitmap
        x_1: int = 0,  # source x start
        y_1: int = 0,  # source y start
        x_2: int = None,  # source x end
        y_2: int = None,  # source y end
        skip_index: int = None,  # palette index that will not be copied
        # (for example: the background color of a glyph)
    ) -> None:
        # pylint: disable=no-self-use, too-many-arguments

        if hasattr(bitmap,
                   "blit"):  # if bitmap has a built-in blit function, call it
            # this function should perform its own input checks
            bitmap.blit(
                x,
                y,
                source_bitmap,
                x1=x_1,
                y1=y_1,
                x2=x_2,
                y2=y_2,
                skip_index=skip_index,
            )

        else:  # perform pixel by pixel copy of the bitmap

            # Perform input checks

            if x_2 is None:
                x_2 = source_bitmap.width
            if y_2 is None:
                y_2 = source_bitmap.height

            # Rearrange so that x_1 < x_2 and y1 < y2
            if x_1 > x_2:
                x_1, x_2 = x_2, x_1
            if y_1 > y_2:
                y_1, y_2 = y_2, y_1

            # Ensure that x2 and y2 are within source bitmap size
            x_2 = min(x_2, source_bitmap.width)
            y_2 = min(y_2, source_bitmap.height)

            for y_count in range(y_2 - y_1):
                for x_count in range(x_2 - x_1):
                    x_placement = x + x_count
                    y_placement = y + y_count

                    if (bitmap.width > x_placement >= 0) and (
                            bitmap.height > y_placement >=
                            0):  # ensure placement is within target bitmap

                        # get the palette index from the source bitmap
                        this_pixel_color = source_bitmap[y_1 + (
                            y_count * source_bitmap.width
                        )  # Direct index into a bitmap array is speedier than [x,y] tuple
                                                         + x_1 + x_count]

                        if (skip_index is None) or (this_pixel_color !=
                                                    skip_index):
                            bitmap[  # Direct index into a bitmap array is speedier than [x,y] tuple
                                y_placement * bitmap.width +
                                x_placement] = this_pixel_color
                    elif y_placement > bitmap.height:
                        break