怎么在LVGL 8.3上显示条形码
- 基于code128库实现对数据的解码
- 转化成lv_img_dsc_t数据
- 用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);
}