Is there any problem with image scaling?

Description

LittlevGL version: v7.0.0
I want to scale the image, and the test found something wrong.

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

BLE MCU(ARM)

What do you experience?

After many tests, I found that there is a problem with the scaling of the picture type LV_IMG_CF_TRUE_COLOR, and the LV_IMG_CF_TRUE_COLOR_ALPHA can display normally.

What do you expect?

I expect the picture to scale properly(image_type: LV_IMG_CF_TRUE_COLOR).

Code to reproduce

Add a code snippet to reproduce the issue in the simulator. It should contain only the relevant code which can be compiled. Bug reports without code snippets or with erroneous code snippets will not be reviewed.

	lv_obj_t *screen = lv_scr_act();
    lv_obj_t *img_origin = lv_img_create(screen, NULL);
    lv_img_set_src(img_origin, &BIN_IMAGE_2);
	lv_obj_set_pos(img_origin, 10, 10);
	
	lv_obj_t *img_zoom = lv_img_create(screen, NULL);
    lv_img_set_src(img_zoom, &BIN_IMAGE_2);
	lv_img_set_antialias(img_zoom, true);
	lv_img_set_auto_size(img_zoom, true);
	lv_img_set_zoom(img_zoom, 256 / 2);
	lv_obj_align(img_zoom, img_origin, LV_ALIGN_OUT_RIGHT_TOP, 20, 30);

Screenshot and/or video

If possible, add screenshots and/or videos about the current issue.
image

@kisvegabor

Looking forward to your reply.

Best Regards.

Please send a copy of BIN_IMAGE_2 as well.

OK!
BIN_IMAGE_2.c (1.9 MB)
news_tu_1

Hi,

I’ve fixed it here:

Thank you for your reply.
After the update, the effect is much better, but there are still some problems.

The test found that when the picture is zoomed out, it seems that the graphics have some changes (from Right, Bottom edge position). Is there any way to optimize this?

@kisvegabor

Please attach the images and your test code.

OK, please wait a moment.

[ Attach Files ]
test_code.zip (105.8 KB)

Regarding the LV_IMG_CF_TRUE_COLOR image to achieve transparent display,
I made some modifications as follows:
@ src / lv_draw / lv_draw_blend.c -> map_normal (…)

'[ original code ]' >>
memcpy(&disp_buf_tmp[draw_area->x1], map_buf_tmp, draw_area_w * sizeof(lv_color_t));
'[ modified code ]' >>
for (int index = 0; index < draw_area_w; index ++) {
     lv_color_t color = map_buf_tmp[index];
     int brightness   = lv_color_brightness(color);

     if (brightness < 10) {
         continue;
     } else if (brightness < 60) {
         color = lv_color_mix(color, disp_buf_tmp[draw_area->x1 + index], brightness);
     }

     disp_buf_tmp[draw_area->x1 + index] = color;
}

@kisvegabor

My guess is that it’s caused by the use of a very simple scaling algorithm. It’s probably not going to work well with extreme downsizing of images.

I think it can be optimized better, because I achieved this effect with a simple scaling algorithm.
image

public Bitmap IMG_Zoom(Bitmap img, int w, int h)
{
    Bitmap IMG = new Bitmap(w, h);

    int w0 = img.Width;
    int h0 = img.Height;

    int w1 = w;
    int h1 = h;

    float fw = ((float)w0 / (float)w1);
    float fh = ((float)h0 / (float)h1);

    int y1, y2, x1, x2, x0, y0;
    float fx1, fx2, fy1, fy2;
    for (int y = 0; y < h1; y++)
    {
        y0 = (int)(y * fh);
        y1 = y0;
        if (y1 == h0 - 1) y2 = y1;
        else y2 = y1 + 1;

        fx1 = y1 - y0;
        fx2 = 1.0f - fx1;

        fy1 = y1 - y0;
        fy2 = 1.0f - fy1;

        float s1 = (fx1 * fy1);
        float s2 = (fx2 * fy1);
        float s3 = (fx2 * fy2);
        float s4 = (fx1 * fy2);

        for (int x = 0; x < w1; x++)
        {
            x0 = (int)(x * fw);
            x1 = x0;
            if (x1 == w0 - 1) x2 = x1;
            else x2 = x1 + 1;

            Color c1, c2, c3, c4;
            c1 = img.GetPixel(x1, y1);
            c2 = img.GetPixel(x2, y1);
            c3 = img.GetPixel(x1, y2);
            c4 = img.GetPixel(x2, y2);
            byte r, g, b;
            r = (byte)((byte)(c1.R * s3) + (byte)(c2.R * s4) + (byte)(c3.R * s2) + (byte)(c4.R * s1));
            g = (byte)((byte)(c1.G * s3) + (byte)(c2.G * s4) + (byte)(c3.G * s2) + (byte)(c4.G * s1));
            b = (byte)((byte)(c1.B * s3) + (byte)(c2.B * s4) + (byte)(c3.B * s2) + (byte)(c4.B * s1));

            if (x >= IMG.Width) break;
            if (y >= IMG.Height) break;

            IMG.SetPixel(x, y, Color.FromArgb(r, g, b));
        }
    }

    return IMG;
}

Looking forward to your optimization. :grinning:

Best Regards.

Where did you retrieve this code from? Did you create it by hand?

This is an image scaling program I tested with Visual Studio C# (Winform).

Hello!
Is there any plan to consider optimization?

Please be patient; @kisvegabor will respond when he gets a chance.

Okay, very looking forward.

Hello! Any progress? :slightly_smiling_face:
@kisvegabor

He is working on it; unfortunately he has been busy with other things over the last few days so he hasn’t gotten a chance to reply.

Okay, I see.
Thanks in advance.

Hello!
I have now modified lv_img_draw_core (…). From the perspective of the running effect, the effect has been significantly improved. :grinning: