Weird background on GIFs

Description

I am getting a weird background on my GIFs as I cycle through them. It is worth noting that I am currently converting my GIFs to C arrays with a CF_RAW color format using LVGL’s online image converter tool. Sometimes, the background flashes white before turning transparent again. Other times, it flashes a different color. I have also observed cases where a white background persists, but the bounding box around the image is transparent.

What MCU/Processor/Board and compiler are you using?

ESP32 Lyra-T/gcc

What LVGL version are you using?

v8.3

What do you want to achieve?

I would like to be able to play GIF all the way through and have it retain its transparent background.

What have you tried so far?

  • Experimenting with different GIFs
  • Trying different variations of the CF_RAW color format when using the online converter.
  • Using the LVGL simulator on Eclipse (same issue)
  • Loading a GIF from file (same issue)

Code to reproduce

    SemaphoreHandle_t xGuiSemaphore = get_semaphore();

    // Init the gif object one time
    if(!gif) {
        gif = lv_gif_create(lv_scr_act());
    }

    while (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) != pdTRUE) {}

    lv_gif_set_src(gif, &mario_example);
    lv_obj_align(gif, LV_ALIGN_CENTER, 0, 0);

    xSemaphoreGive(xGuiSemaphore);

Screenshot and/or video

In these two examples, a colored background flashes before the GIF reverts to its original transparent state.

IMG_4122
IMG_4123

It’s harder to tell with the ghost, but you can see the outline of the bounding box near the bottom of the screen.

IMG_4124
IMG_4125

Is this issue solved? I’m having the same issue with my GIF loading. It’s with a green background at the very beginning.

I’ve also seen this problem. It looks to be related to how transparent backgrounds are handled. When the gif decoder is initialized, the canvas is filled with the background color, and full opacity. It looks like consider LV_COOR_DEPTH to lower memory usage · lvgl/lv_lib_gif@596cb32 · GitHub was the commit that introduced this change.

Note that the “return to background color” disposal method seems to switch on whether the last graphical control extension had transparency set to 1. Blaming lv_lib_gif/gifdec.c at master · lvgl/lv_lib_gif · GitHub

Interestingly, the 89a gif specification is rather sparse in describing how the global Background Color Index and local Transparency Color Indexes should interact. Background Color is described as:

The Background Color is the color used for those pixels on the screen that are not covered by an image.

While transparency Index is described as:

The Transparency Index is such that when encountered, the corresponding pixel of the display device is not modified and processing goes on to the next pixel.

It seems somewhat open to interpretation how transparent backgrounds should be handled. The de-facto standard with modern gif decoders (e.g. in web browsers) seems to be to treat the background as transparent by default.

@kisvegabor do you have thoughts on this one? It seems like at one point in time, gifdec did handle background as transparent by default.

To save memory and for the sake of simplicity I started to think about supporting only global color table. This way the decoding would be much simpler and we could use a single INDEXED_8BIT color format. (meaning widht x height byte RAM usage).

What do you think about it?

I had the same issue with transparent GIFs and I was able to solve it, although I don’t know if the solution is optimal.

What is causing the issue?

When opening the GIF from the file, the gif library renders the first frame on its own, without using the frame render method. What you see in fact is the first background color that should have been trasparent (you can compare the color from the “trasparency color” value given uploading the GIF on onlinegiftools.com).

What is the solution to this?

The simplest solution is to change line 148 (if you have 16bit depth, 143 for 32bit and 152 for 8bit) to gif->canvas[i*3 + 2] = 0x00;. This will set the first background to trasparent.
I don’t know if it could cause an inverse problem (GIFs with solid bg displaying partially trasparent) so a check should be added, like at line 515. I tried adding something but without success.
I guess @kisvegabor can figure a smarter way to do this :sweat_smile:

Each line refers to lv_lib_gif/gifdec.c

I’m not sure, I was also just hacking with the gif decoder :smiley:
However, it recevied some update in the v9-dev (master branch). Could you check if the issue is still persists?

I’m using PlatformIO, with ESP32-arduino, and the last available library version for me is v8.3.9. However looking into gifdec.c > gif_open() looks like at line 148 the check is not done yet, so my guess is that the bg will be still bugged.
I should set up another test project I think to test this, so I’ve no way to know for sure yet. If I got some time I can try it out!

finally, you have solved my problem, I think it is really a bug, should be updated in branch.

Oh, I find there is still a problem, the last frame will stay in next cycle at first frame, if last frame isn’t the same as first frame or first frame can not cover last frame, it will display two frame together.