Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

image with alpha channel is broken #25

Open
glory-man opened this issue Nov 2, 2021 · 12 comments
Open

image with alpha channel is broken #25

glory-man opened this issue Nov 2, 2021 · 12 comments

Comments

@glory-man
Copy link
Contributor

I used such image - 4 rectangles filled with almost the same color but different alpha value
bitmap

After it drawed on the screen it looks strange - with lines, although rectangles at the source image has solid filled alpha-channel
IMG_20211102_173710

@kisvegabor
Copy link
Member

If you use lvgl v8 can you try lvgl master? The PNG lib was merged there:

https://docs.lvgl.io/master/libs/png.html

@glory-man
Copy link
Contributor Author

glory-man commented Nov 5, 2021

If you use lvgl v8 can you try lvgl master? The PNG lib was merged there:

https://docs.lvgl.io/master/libs/png.html

I use lvgl v7.6.1 and code from lv_png v7 branch

@glory-man
Copy link
Contributor Author

glory-man commented Nov 5, 2021

One more moment. For example, I use png from this issue.
This picture have white car on a black background with blur under the car body
car_noalpha
Alpha channel
car_alpha
If we bring the channels together, then the image on a white background should give a car with a shadow under it. Something like this
expectation
But on the screen I see car and dark shaddow where alpha value has large value
IMG_20211105_180916

I use lvgl-settings given in this discussion. Could the LV_COLOR_DEPTH=16 have any effect on this?

@kisvegabor
Copy link
Member

I suggest taking a look at this function: https://github.com/lvgl/lv_lib_png/blob/master/lv_png.c#L214
Maybe the color channels are mixed here 🙁

@glory-man
Copy link
Contributor Author

glory-man commented Nov 11, 2021

I suggest taking a look at this function: https://github.com/lvgl/lv_lib_png/blob/master/lv_png.c#L214 Maybe the color channels are mixed here 🙁
I tried with such pic - 64x64 px, 4 rectangles - with color 0x00FF00, but different alpha value - 0xFF, 0xBF, 0x80, 0x40
test1

I see following images on the screen

IMG_20211111_131709
IMG_20211111_131715

Img_data variable data-dump before call
convert_color_depth(img_data, png_width * png_height);
img_data_before_convert.txt

and after
img_data_after_convert.txt

It seems like colors converted correctly. But drawed image contains stripes. So it seems lvgl-image-draw worked incorrectly with img_data received from decoder -> lvgl itself issue.

@kisvegabor
Copy link
Member

Hmm, I'd be very surprised if LVGL had a bug in simply displaying and image.

Can you reproduce in a simulator? If so please send me the commit hash of LVGL your are using and a short codsnippet to be sure we are doing the very same thing.

@glory-man
Copy link
Contributor Author

Hmm, I'd be very surprised if LVGL had a bug in simply displaying and image.

Can you reproduce in a simulator? If so please send me the commit hash of LVGL your are using and a short codsnippet to be sure we are doing the very same thing.

I tried to debug how img_draw worked with my image.
lv_draw_map() called from lv_img_draw_core() blended img data with background piece by piece. In my case with image is 64x64, blended area calculated as 11px height and 64px width. After that called _lv_blend_map() where
there is lines

    {
        int32_t mask_w = lv_area_get_width(&draw_area);
        int32_t i;
        for(i = 0; i < mask_w; i++)  mask[i] = mask[i] > 128 ? LV_OPA_COVER : LV_OPA_TRANSP;
    }

which resets first line of mask buffer to 0/255 (as if this line should be completely transparent for the top half of the image where alpha channel < 128, or opaque for bottom half where alpha > 128). So after blending (in my case with map_normal() ) I see first line transparent/opaque (background/map color - clearly visible on a red background), next 10 lines normal (as it should be in image).
The same happens for the next part of the image.

So in case of big picture (like in this post) image will be blended line by line and alpha channel values will be LV_OPA_COVER or LV_OPA_TRANSP.

@kisvegabor
Copy link
Member

Wow, it's really a bug if antialiasing is disabled. I've merged lvgl/lvgl#2803 where I fixed it in this commit.

But not that with antialiasing enabled you can't draw ARGB images because the alpha channel will be rounded to 0 or 255.

@glory-man
Copy link
Contributor Author

glory-man commented Nov 26, 2021

Wow, it's really a bug if antialiasing is disabled. I've merged lvgl/lvgl#2803 where I fixed it in this commit.

Now, in latest commit, if antialiazing is disabled alpha channel will be rounded for full blended area, and as a result for whole drawn image. And if png-image have alpha-channel those values will be ignored. Am I understand correctly ?

@kisvegabor
Copy link
Member

Not ignored but there won't be semi-transparent pixels. Only 0% or 100% alpha.

Note that even with antialising=0 ARGB images could be drawn correctly as they have nothing to do with antialiasing. But antialiasing is handled here because all drawing ends up in the to blend function and it's convenient to handle it here.

Just out of curiosity, why do you need antialaising=0?

@glory-man
Copy link
Contributor Author

Just out of curiosity, why do you need antialaising=0?

This option disabled by default in zephyr-config. But I didn't think it could be such important. I thought that anti-aliasing should help remove the distortion artifacts on the edges, but I ran into the PNG image losing its alpha channel on output, or drawed as broken.

@glory-man
Copy link
Contributor Author

Note that even with antialising=0 ARGB images could be drawn correctly as they have nothing to do with antialiasing. But antialiasing is handled here because all drawing ends up in the to blend function and it's convenient to handle it here.

By the way, in my example, the PNG image is presented in ARGB (after lodepng_decode32() decoding, a 32-bit array was obtained), but since the LV_COLOR_DEPTH is set to 16 decoder_open() converted it to 3-byte (16bit color + aplha) array, and after that image blended.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants