Displaying colored bitmaps from PROGMEM

I have a 3.5" TFT 480x320 display and the MCUFRIEND_kbv library and I'm trying to display a colored picture.
I've tried using setAddrWindow() and pushColors() but I just dont understand the parameters required.

For setAddrWindow() I know the first two parameters are just the coordinates and I guess the last two are width and height, and I say (I guess) because in the graphics_kbv example this is written:

tft.setAddrWindow(wid - 40 - 40, 20 + 0, wid - 1 - 40, 20 + 39);

If the last two parameters are width and height then why did they type it like that?

and for pushColors() the first parameter is the bmp array, idk the rest.

Sorry if this is a stupid question but I've been searching for hours and there is no documentations that explain them.

Tysm.

Look at the header file e.g. C:\Users\David Prentice\Documents\Arduino\libraries\Mcufriend_kbv\MCUFRIEND_kbv.h

	void     setAddrWindow(int16_t x, int16_t y, int16_t x1, int16_t y1);

x, y are top left hand corner. x1, y1 are the bottom right hand corner.

Yes, I agree that x, y, w, h would be more intuitive.

Historically, the Adafruit hardware libraries used x, y, x1, y1 e.g. in the original Adafruit_TFTLCD and Adafruit_ILI9341
Which is why MCUFRIEND_kbv followed the x, y, x1, y1 style.

However, Adafruit changed their libraries several years ago to the x, y, w, h style.

I suggest that you look at the drawBitmap_kbv example that shows the GFX methods. (and how to use pushColors() )

You have to be realistic. Full colour bitmaps can be very large. Hence you read from SD card rather than embed in PROGMEM memory.

JPG images can use memory very efficiently but you need about 4kB SRAM to decode them.

As always, if you say what you really want to do, it is easier to answer. e.g. example image, size, ...

David.

Thanks for the quick reply, alright so I tried it with a 54*148 picture so it should be like this right ?

tft.setAddrWindow(0, 0, 58, 148); //58x148
tft.pushColors(logo, 58*148, 1);

But it still doesnt work. here is my graphics.c and the original picture:

graphics.c (159 KB)

pls.png

nvm I think I didnt convert it in the correct format. I used Rinky-Dinky Electronics to convert it but it still doesnt work.

Your PNG is 54x148 i.e. 7992 pixels. 16-bit pixels would be 7992 uint16_t or 15984 uint8_t

Your C file is

const unsigned char PROGMEM logo[26102] = {

How did you generate your C file?
My examples show several methods of generating colour bitmaps.

Have you actually studied the drawBitmap_kbv.ino example ?

Your image can fit in PROGMEM as a C array. Note that the AVR compiler will only allow arrays < 32768 bytes.

David.

Yeah I've just learnt there are different formats. I just copy pasted the array elements into the first array I've made which was for another picture.
I've just tried Rinky-Dinky Electronics and now it displays the correct colors at least, But it's still scrambled.

I read about drawRGBBitmap (int16_t x, int16_t y, const uint16_t bitmap[], int16_t w, int16_t h)
but it's not a member of the MCUFRIEND_kbv library:
'class MCUFRIEND_kbv' has no member named 'drawRGBBitmap'
even in the provided example it doesnt work.

I got it to work btw tysm for the redirection <3

Hardizzer:
I read about drawRGBBitmap (int16_t x, int16_t y, const uint16_t bitmap[], int16_t w, int16_t h)
but it's not a member of the MCUFRIEND_kbv library:
'class MCUFRIEND_kbv' has no member named 'drawRGBBitmap'
even in the provided example it doesnt work.

class MCUFRIEND_kbv inherits from Adafruit_GFX and Print

This means that you can do everything that Adafruit_GFX can do. e.g. drawRGBBitmap()

Some things are done better than the basic Adafruit_GFX method e.g. fillScreen(), pushColors(), ...
I don't "improve" drawRGBBitmap() but other hardware libraries do provide a hardware speedup of drawRGBBitmap() e.g. Adafruit_ILI9341

Inheritance is the overwhelming feature of C++ over the original C.

If you studied my example, you would have created a C array of uint16_t pixels with RinkyDink tool.
Then displayed it with drawRGBBitmap()
And then displayed with setAddrWindow() and pushColors()

setAddrWindow() and pushColors() is a bit fiddly. So you could write a helper function with arguments like tft.drawRGBBitmap() that calls setAddrWindow() and pushColors().

David.

david_prentice:
setAddrWindow() and pushColors() is a bit fiddly. So you could write a helper function with arguments like tft.drawRGBBitmap() that calls setAddrWindow() and pushColors().

Yeah, I've already done so. ty again.