Converting images for display

I am trying to convert images to put on my display. When I use the penguin which came with the library, it works fine. (40x40 px image)

extern const uint8_t penguin[];
x=439,y=1,px=40,py=40;
tft.setAddrWindow(x, y, x+(px-1), y+(py-1));
tft.pushColors(penguin, 1600, 1);

But when I try to use the one I converted with LCD Image Converter, I only get a little of the bottom of the image. (32x32 px image)

I still use the same code to calculate position and size, but calling the new image instead.

extern const uint8_t wifi_full[];
int x=479-32,y=1,px=32,py=32;
tft.setAddrWindow(x, y, x+(px-1), y+(py-1));
tft.pushColors(wifi_full, 1600, 1);

Converted image is posted here http://pastebin.com/eRt7Y5B5 to make the post an allowed length.

I am not sure what goes wrong here, the top half of the image seems to be random dots, and the bottom half is displayed correct.

The image I am experimenting with is this one Sl, media, wifi, social icon - Free download on Iconfinder

Does anyone else have some experience with converting images like this?

pushColors() has two overloaded methods. The one that uses PROGMEM expects little-endian pixels. i.e. each pixel uses two uint8_t bytes. low-high.

I suspect that you have got your bytes in high-low order.

You have set your 32x32 window correctly.
But you have specified 40x40 pixels rather than 32x32 pixels.
Mind you, the window should just ignore any extra pixels after you have filled all 32x32 pixels.

extern const uint8_t wifi_full[];
int x=479-32,y=1,px=32,py=32;
tft.setAddrWindow(x, y, x+(px-1), y+(py-1));
tft.pushColors(wifi_full, 32 * 32, 1);

Sorry about the convoluted arguments. Most AVR or 8051 data is little-endian. But the TFT expects big-endian data.

David.

Ah-ha. If you send more pixels to pushColors() than the window can hold, it continues filling.

I have extended the pushColors() from Flash method with an optional argument.
I have just pushed onto the Master branch of GitHub.

	void     pushColors(uint16_t *block, int16_t n, bool first);
	void     pushColors(uint8_t *block, int16_t n, bool first);
	void     pushColors(const uint8_t *block, int16_t n, bool first, bool bigend = false);

It should not affect any existing code. But will give you flexibility with external Image Converters. e.g.

//            tft.setAddrWindow(wid - 40 - 40, 20 + 0, wid - 1 - 40, 20 + 39);
//            tft.pushColors(penguin, 1600, 1);
            tft.setAddrWindow(wid - 40 - 40, 20 + 0, wid - 40 - 40 + 31, 20 + 31);
            tft.pushColors(wifi_full, 1024, 1, true);

This places your Wifi icon at the same X, Y as the Penguin but with a 32x32 window.
And pushes 32x32 pixels from Flash stored in a Bigendian order.
It also means that you can display icons that were stored as uint16_t and not uint8_t. Just cast the address with (const uint8_t *) to make sure you call the correct overloaded method.

I would appreciate your comments. This makes pushColors() different to the original Adafruit. That only has a (uint8_t *) method.

David.

aaaah yes, you are right! I totally missed I didnt put the right value into the pushColors call.

I changed my code to this, so it helps me calculate it properly.

extern const uint8_t wifi_full[];
int x=479-32,y=1,px=32,py=32;
tft.setAddrWindow(x, y, x+(px-1), y+(py-1));
tft.pushColors(wifi_full, px*py, 1);

Worked right away! :slight_smile:

I might try tour change, but for now I am just playing around with this :slight_smile: