How to get proper transparency on images ? I have noise on rendering

First thank you for this amazing library:smiley:

I am using ESP32 + ILI9488 screen and XPT2046 touch, under window the lv_arduino-2.0.3 library with TFT_eSPI-1.4.11 library and latest ESP32 git core

my LV_COLOR_DEPTH is 16
and I have set LV_COLOR_TRANSP LV_COLOR_MAKE(0xFF, 0x00, 0xFF) (issue is same with original color)

I have converted this jpg with online converter tool using True color chroma keyed and Binary RGB565 to bin file

logo
I use Paint.net to create initial image

The generated bin file is copied to SPIFFS partition, I have wrote a SPIFFS wrapper following online documentation and it seems working.

The issue is that global rendering of picture is noisy, still some dots appear around not transparent areas when should be transparent
Here the picture : (sorry for quality)

here a zoom for reference, purple follow the line and noise purple dots are all around

I have tried every format and settings in online converter - redo the picture to be sure the noise does not come from original picture, I use jpg because png rendering is not correct, like a blue filter on image.
If I use full transparent image (filled with transparent color) no noise, image is fully transparent =>ok
If I do not use transparent color, no noise but image of course has no transparency=>ok

Do I miss some settings ? Do I do something wrong ?
Or it is a bug with transparency ? Or with Online converter ?
I do not know where to look at, thanks for your help

You’ll have to use PNG if you want it to work properly. JPEG compression will mess up the chroma keying.

1 Like

OK thank you, it is good to know jpg is not the good choice for transparency

I will focus on png then, it may be some default settings when saving that are not corrects.

Seems I tested all settings but right one :crazy_face:

By default when saving png Bit Depth was set to Auto-detect which bring random rendering depending on content: black image, blue image, etc, set 8 bits or 32 bits give same results, but looks like 24bits is ok, no noise, proper rendering.
Windows Paint does not give choice and seems ok out of the box.

I am not familiar with image settings, I was confused with LV_COLOR_DEPTH 16 so did not tried the 24bits.:sweat:

thank you for the help, really appreciate

(cc @kisvegabor)

This is interesting. Ideally the image converter should be able to handle PNGs of any depth. Maybe this is something we need to look into? I’ll test it soon.

I’ve never tested it but I assume with lower color depth it tells the pixel values as they are. So if Red has 0…31 range it doesn’t scale it up to 0…255.

I’ve added a note about it on the converter’s site: https://littlevgl.com/image-to-c-array

One note about transparency, may be it is a known issue :
Using Theme will affect transparency rendering, for example using green as transparent color will stay green in image if Mono theme is used but will be transparent with default theme.

Could you send the converted image?

Which color depth do you use?

Well this is embarassing - it seems I am back to square 1 - issue I thought coming from theme, came in fact from conversion, even in normal theme transparency is not taken in account, (using new snap feature)

image ![logo|200x150]
I enclose the original png file : logo.zip (2.5 KB)
and the converted file
esplogo.c (1.5 MB)

done by :

and related conf settings

/* Maximal horizontal and vertical resolution to support by the library.*/
#define LV_HOR_RES_MAX          (480)
#define LV_VER_RES_MAX          (320)

/* Color depth:
 * - 1:  1 byte per pixel
 * - 8:  RGB233
 * - 16: RGB565
 * - 32: ARGB8888
 */
#define LV_COLOR_DEPTH     16

/* Swap the 2 bytes of RGB565 color.
 * Useful if the display has a 8 bit interface (e.g. SPI)*/
#define LV_COLOR_16_SWAP   0

/* 1: Enable screen transparency.
 * Useful for OSD or other overlapping GUIs.
 * Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/
#define LV_COLOR_SCREEN_TRANSP    0

/*Images pixels with this color will not be drawn (with chroma keying)*/
#define LV_COLOR_TRANSP    LV_COLOR_LIME 

/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
#define LV_ANTIALIAS        1

I am sure I was able to do transparency before, but not anymore :confused:
The difference is before I used external binary when now I use C array, I think.

Check that LV_COLOR_LIME has the same RGB value as the green pixels in your PNG file (using something like GIMP). It’s possible that they are slightly different shades of green. You might need to modify LV_COLOR_TRANSP appropriately.

yes it does,
image

#define LV_COLOR_LIME LV_COLOR_MAKE(0x00, 0xFF, 0x00)

It’s working for me:
image

    LV_IMG_DECLARE(esplogo)
    lv_obj_t * img = lv_img_create(lv_scr_act(), NULL);
    lv_img_set_src(img, &esplogo);

What do you get for this?

    printf("%d\n", lv_img_color_format_is_chroma_keyed(esplogo.header.cf));

It should be 1.

1 Like

Yes it is - I even revert to initial sample code an just add the image
ESP32_TFT_eSPI.zip (22.0 KB)

Still no transparency - I am really lost

ok changing in lv_conf.h

#define LV_COLOR_TRANSP LV_COLOR_MAKE( 0x00, 0xFF, 0x00)
to
#define LV_COLOR_TRANSP LV_COLOR_MAKE( 0xFF, 0x00, 0xFF)

and changing to same color in png and transparency is back with sample code that previously failed,
and this is the color I used in inital test

So my config does not like green

and I confirme now ok on my main program.
image
and to come back to the note : the issue is not the theme, transparency works well with mono theme
image

Sorry for the confusion - I did not trigged the root cause properly

Issue is definively the green transparency not seen on my 16 Bit depth system, could it be because of this bit depth and so color 0x00, 0xFF, 0x00 can not be reached due to RGB565 ?

It is not a real problem now I know ^_^: Png 24bit and 0xFF, 0x00, 0xFF for transparency color

The first pixel in the converted image has 0xe0, 0x07 value. It’s Little endian so the real value is 0x07, 0xe0. In binary 0000 0111 1110 000. In RGB565 R00000, G111111, B00000. So the converted image should be fine.

The chrome keying is handled here:

It should be worth some debugging to see what have happened.

Ok I will check and report later

I have added line 504 :

if ((col == 0)&& (row == 0)) {
                    printf("chroma_key: %#08X, px_color.full:%#08X, chroma_key && px_color.full:%#08X, disp->driver.color_chroma_key.full:%#08X\n",chroma_key, px_color.full, chroma_key && px_color.full, disp->driver.color_chroma_key.full);
                }

with

#define LV_COLOR_TRANSP    LV_COLOR_MAKE(  0xFF, 0x00, 0xFF)

and purple image bg I got transparency and output is :
chroma_key: 0X000001, px_color.full:0X00F81F, chroma_key && px_color.full:0X000001, disp->driver.color_chroma_key.full:0X00F81F

with

#define LV_COLOR_TRANSP    LV_COLOR_MAKE( 0x00 , 0xFF, 0x00) 

and green image bg I do not get transparency and output is:
chroma_key: 0X000001, px_color.full:0X0007E0, chroma_key && px_color.full:0X000001, disp->driver.color_chroma_key.full:0X00F8

I enclose the 2 images sources and mcve
ESP32_TFT_eSPI.zip (50.9 KB)

Edit : I realize I misread chroma_key && px_color.full == disp->driver.color_chroma_key.full
should be : chroma_key && (px_color.full == disp->driver.color_chroma_key.full) to avoid confusion, but output is still meaninful

Let me know if you need me to add more info on debug

What is the RGB type of the image before conversion? 16-bit or 32-bit?

I use 24bits as this is the one working for me with the online converter as mentioned earlier
image -
same used for green background and purple background