Skip to content

Latest commit

 

History

History
74 lines (68 loc) · 3.11 KB

221029.bitmap.md

File metadata and controls

74 lines (68 loc) · 3.11 KB

2022-10-29

https://discordapp.com/channels/918498540232253480/918498540232253483/1035844732418539541

Matthias
I'm playing around with the display. Everything works fine so far. But I having trouble to display a bitmap. Is there somewhere an example? I found a bitmap function in TrueColorPixelDisplay that returns a texture. And the texture has a write method. But the write method does not take bits. It asks for a Canvas but does not really work for me This works:

texture := tft.bitmap sans_big_context 100 100 10 10
  texture.set_pixel 0 0
  texture.set_pixel 1 1
  texture.set_pixel 2 2
  texture.set_pixel 3 3
  texture.set_pixel 4 4

but

c := Canvas 1000 1000 0 0
  c.set_pixel WHITE 0 0 
  c.set_pixel WHITE 1 1 
  c.set_pixel WHITE 2 2 
  texture.write c

does not
I guess texture.write is somehow the way to feed a bitmap as bytearray The examples all work with fonts or icons (technically also a font). But how to load a Bitmap?

erikcorry —
Hi Canvas is not really intended to be used by library users.
Normally you have a display of some sort. That's probably the tft you have above.
You add textures (objects) to the display. One of those could be a bitmap, like you did above.
Then when you want to update the screen you call draw.
It makes a bunch of small Canvases, each of which is small enough to fit in memory. They are tiles of the display.
It renders the textures onto each canvas and flushes it to the hardware display, then makes a new Canvas with the next tile, etx.
Since memory is very limited on the device you won't normally be creating huge bitmaps.
But if you need bitmaps that are more than one colour you can use IndexedPixmapTexture
IndexedPixmapTexture can't be created with a call on the tft display object, so you have to create one with its constructor, then add it to the display.

Untested code, but something like:

landscape := tft.landscape_context
X := 0
Y := 0
pixmap := IndexedPixmapTexture 64 64 X Y landscape   // 64x64 means a 4k buffer.
red := pixmap.allocate_color 255 0 0
pixmap.set_pixel 42 42 red
tft.add pixmap
tft.draw

You could make a small Icon with

IMAGE ::= #[
    0, 0, 0, 1, 1, 0, 0, 0,
    0, 0, 1, 2, 2, 1, 0, 0,
    0, 1, 2, 3, 3, 2, 1, 0,
    1, 2, 3, 4, 4, 3, 2, 1,
    1, 2, 3, 4, 4, 3, 2, 1,
    0, 1, 2, 3, 3, 2, 1, 0,
    0, 0, 1, 2, 2, 1, 0, 0,
    0, 0, 0, 1, 1, 0, 0, 0]

PALETTE ::= #[
    0, 0, 0,
    255, 0, 0,
    128, 255, 0,
    0, 0, 255]

pixmap := IndexedPixmapTexture 8 8 0 0 landscape IMAGE PALETTE

The display library is quite oriented towards the fonts and icons because they are compressed and can stay in ROM/Flash. Anything that actually involves manipulating images in RAM tends to run out of space pretty fast.
That said we need some sort of compressed bitmap format. PNG is not great because the decompression can take up to 32k and you have to decompress the whole image, potentially, to just draw a small part of it.
There is a pseudo-display at https://pkg.toit.io/package/github.com%2Ftoitware%2Ftoit-png-display.git@v0.2.0 which writes PNGs instead of updating a physical display.
Easier to play with on Linux.