Bootstrap

LVGL 8.3 条形码的显示

怎么在LVGL 8.3上显示条形码

  1. 基于code128库实现对数据的解码
  2. 转化成lv_img_dsc_t数据
  3. 用img控件显示

一、解码

如果不了解code128算法,可以先去了解一下。

先获取输入数据的长度, 再根据长度申空间给到code128算法,然后解析出原始数据。

此时解码出来的barcode_data数据是0或1组成的数组,1即是有数据,也就是条形码中的黑色。

    size_t estimated_length = code128_estimate_len(data);
	LV_LOG_USER("estimated_length :%d\n", estimated_length);
    char *barcode_data = (char *)lv_mem_alloc(estimated_length);
	if(barcode_data == NULL)
	{
		LV_LOG_USER("malloc_psram barcode_data err\n");
		return NULL;
	}
    size_t actual_length = code128_encode_raw(data, barcode_data, estimated_length);


    int min_width = actual_length * 2;
    if (width < min_width) {
        width = min_width;
    }

二、转化数据

条形码一般默认是以白色为底,黑色为显示数据的颜色。

此时我们跟据barcode_data数据,如果是1就填充黑色,否则白色。

    lv_color_t *img_buf = (lv_color_t *)lv_mem_alloc(width * height * sizeof(lv_color_t));
	if(img_buf == NULL)
	{
		LV_LOG_USER("malloc_psram img_buf err\n");
		return NULL;
	}
	
    for (int i = 0; i < width * height; i++) {
        img_buf[i] = lv_color_white();
    }

    int unit_width = width / actual_length;
    int remaining_width = width % actual_length;
    int left_padding = (width - (actual_length * unit_width + remaining_width)) / 2;

	int x = left_padding;
    for (size_t i = 0; i < actual_length; i++) {
        lv_color_t color = barcode_data[i] ? lv_color_black() : lv_color_white();
        int bar_width = unit_width + (remaining_width > 0 ? 1 : 0);
        if (remaining_width > 0) {
            remaining_width--;
        }

        for (int j = 0; j < bar_width; j++) {
            for (int k = 0; k < height; k++) {
                img_buf[k * width + x + j] = color;
            }
        }
        x += bar_width;
    }

三、使用img控件显示条形码

刚刚我们把条形码已经转化为lv_img_dsc_t类型的数据,可以用img控件来将它显示出来

	lv_img_dsc_t * img_dsc = generate_barcode_image("123456789.com", 300, 100);

	lv_obj_t * img = lv_img_create(lv_scr_act());
	lv_img_set_src(img, img_dsc);
    lv_obj_center(img);

四、完整代码

lv_img_dsc_t * generate_barcode_image(const char *data, int width, int height)
{
    size_t estimated_length = code128_estimate_len(data);
	LV_LOG_USER("estimated_length :%d\n", estimated_length);
    char *barcode_data = (char *)lv_mem_alloc(estimated_length);
	if(barcode_data == NULL)
	{
		LV_LOG_USER("malloc_psram barcode_data err\n");
		return NULL;
	}
    size_t actual_length = code128_encode_raw(data, barcode_data, estimated_length);
    int min_width = actual_length * 2;
    if (width < min_width) {
        width = min_width;
    }
	LV_LOG_USER("img_buf len :%d\n", width * height * sizeof(lv_color_t));
    lv_color_t *img_buf = (lv_color_t *)lv_mem_alloc(width * height *         
    sizeof(lv_color_t));
	if(img_buf == NULL)
	{
		LV_LOG_USER("malloc_psram img_buf err\n");
		return NULL;
	}

        for (int i = 0; i < width * height; i++) {
        img_buf[i] = lv_color_white();
    }

    int unit_width = width / actual_length;
    int remaining_width = width % actual_length;
    int left_padding = (width - (actual_length * unit_width + remaining_width)) / 2;

	int x = left_padding;
    for (size_t i = 0; i < actual_length; i++) {
        lv_color_t color = barcode_data[i] ? lv_color_black() : lv_color_white();
        int bar_width = unit_width + (remaining_width > 0 ? 1 : 0);
        if (remaining_width > 0) {
            remaining_width--;
        }

        for (int j = 0; j < bar_width; j++) {
            for (int k = 0; k < height; k++) {
                img_buf[k * width + x + j] = color;
            }
        }
        x += bar_width;
    }

    	
    lv_mem_free(barcode_data);

    static lv_img_dsc_t img_dsc;
    img_dsc.header.always_zero = 0;
    img_dsc.header.w = width;
    img_dsc.header.h = height;
    img_dsc.header.cf = LV_IMG_CF_TRUE_COLOR;
    img_dsc.data_size = width * height * sizeof(lv_color_t);
    img_dsc.data = (const uint8_t *)img_buf;

    return &img_dsc;
}

void lv_barcode_demo_test(void)
{
	lv_img_dsc_t * img_dsc = generate_barcode_image("123456789.com", 300, 100);

	lv_obj_t * img = lv_img_create(lv_scr_act());
	lv_img_set_src(img, img_dsc);
    lv_obj_center(img);
}

五、显示效果

;