Add transparency support to indexed images

I have implemented a prototype of this here: https://github.com/tgillbe/lvgl/commit/2cd322bf4735d6410f981559f0ecc8a086b82189

It seems sensible to have support for this. Unfortunately my implementation has a few issues so I was hoping to get some feedback before submitting a PR. The issues I can see with my current implementation are as follows:

  • lv_img_color_format_has_alpha has been changed to take a lv_img_decoder_dsc_t and it scans the decoder user_data to check if any of the palette colors have an alpha component. This could potentially speed up drawing of non-transparent indexed images but my current implementation isn’t viable as it assumes the layout of lv_img_decoder_built_in_data_t (I have LV_USE_FILESYSTEM set to 0). Is there a better way of implementing this? I could just assume has_alpha = true regardless and it will work.
  • I have created a lv_color_full_t type which contains a lv_color_t and lv_opa_t. This is so the colors only need to be translated into the correct format for the display once (on image load), but I would have assumed a type like this already exists. Am I missing it?
  • The current image converter (img_conv_core.php) doesn’t support images with an alpha channel, so I’ve made a python version which does here. Unfortunately it’s hacked together so it’s slow at the moment.

Another benefit is that chroma keyed indexed images could be canned. It would be easier just to use the alpha channel (which is present in indexed images already!)

If you want to test this, there’s an example image provided in the commit in both png format and as c code.

Test image drawn by LVGL on top of a blue background and a string saying “TEST”:

Test image

Colors already contain an alpha member. Is there a reason why you can’t use that?

Only lv_color32_t has an alpha member, on my target I have set LV_COLOR_DEPTH to 16 so there is no alpha member as it’s using lv_color16_t.

I didn’t consider that lv_color_t does have an alpha member if LV_COLOR_DEPTH is set to 32, in which case my lv_color_full_t struct will be wasting a byte (or maybe 4 with padding). Definitely needs a rethink.

On how many bits do store transparency e,g. if you have LV_IMG_CF_INDEXED_2BIT?

The palette for an indexed image is already an array of lv_color32_t (8 bytes each of rgba), regardless of the value of LV_IMG_CF_INDEXED. The nBIT prefix specifies the size of the palette, for example LV_IMG_CF_INDEXED_2BIT indicates that the palette has 4 lv_color32_t elements. I haven’t changed anything in this respect - the palette for an indexed image already includes an alpha component, it’s just ignored currently.

I have thought of a way to improve the issues with my implementation so I’ll update it shortly.

Oh, I see. Awesome idea! Now indexed images support Chrome keying for transparency but it would give more freedom.

The image functions in PHP can’t convert true-color images to indexed very well so the image needs to be converted before uploading.
I’ve tried to create an image with GIMP where the palette contains arbitrary alpha but it seems GIMP can handle only 0% and 100% alpha. Do you have an example indexed image where alpha has arbitrary value?

I should have done this in the first place, it’s a much better demo of the transparency support!

Test image:

LVGL result:

RGBA values are:

  • Blue 0x0000ffff
  • Red: 0xff0000c8
  • Green: radial gradient from 0xd4ff2aff to 0xd4ff2a00

The circles are also anti-aliased in the png.

Still working on that pull-request…

Pull request - https://github.com/littlevgl/lvgl/pull/1183