(Chatgpt辅助)C语言移植Code128B条形码算法到LVGL8.3【附跑通代码】
- <1>CODE128算法简介
- <2>C语言实现算法
- <3>LVGL绘图函数实现
- <4>ChatGPT使用有感
序言:
这篇博客是我在移植条形码过程中,发现CSDN以及Google上面较少关于C语言移植条形码到LVGL的
资料文档。同时又恰好我刚开始使用Chatgpt辅助移植,所以就把相关内容总结整理一遍。我本来是
打算移植code128auto算法的,但是临时有其他事情中断了,所以只能把code128B的内容总结一下,
后续有空我会继续完善这个博客的。
<1>CODE128算法简介
详细的介绍可以参考这个博客:https://blog.csdn.net/walk_ing/article/details/52712641
我对该算法的粗浅概括可以总结为以下几点:
<1>Code128B编码规则:开始位 + 数据位 + 检验位 + 结束位
<2>Code128编码表规定一份对应法则:即你所输入的字符将根据这份表格映射成10(bs)形式,其
中1表示黑色,0表示白色
<3>开始位,校验位,结束位都已经被规定好。只有数据位需要一一对应。
<2>C语言实现算法
根据上述3点总结就可以写出相应的代码
// Code 128字符集
const char* code128_charset_B = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";// code128编码值数组,每个字符占11个单位表示
static const uint16_t s_code128_encode_set[] = {0x6cc, 0x66c, 0x666, 0x498, 0x48c, 0x44c, 0x4c8, 0x4c4, 0x464, 0x648,0x644, 0x624, 0x59c, 0x4dc, 0x4ce, 0x5cc, 0x4ec, 0x4e6, 0x672, 0x65c,0x64e, 0x6e4, 0x674, 0x76e, 0x74c, 0x72c, 0x726, 0x764, 0x734, 0x732,0x6d8, 0x6c6, 0x636, 0x518, 0x458, 0x446, 0x588, 0x468, 0x462, 0x688,0x628, 0x622, 0x5b8, 0x58e, 0x46e, 0x5d8, 0x5c6, 0x476, 0x776, 0x68e,0x62e, 0x6e8, 0x6e2, 0x6ee, 0x758, 0x746, 0x716, 0x768, 0x762, 0x71a,0x77a, 0x642, 0x78a, 0x530, 0x50c, 0x4b0, 0x486, 0x42c, 0x426, 0x590,0x584, 0x4d0, 0x4c2, 0x434, 0x432, 0x612, 0x650, 0x7ba, 0x614, 0x47a,0x53c, 0x4bc, 0x49e, 0x5e4, 0x4f4, 0x4f2, 0x7a4, 0x794, 0x792, 0x6de,0x6f6, 0x7b6, 0x578, 0x51e, 0x45e, 0x5e8, 0x5e2, 0x7a8, 0x7a2, 0x5de,0x5ee, 0x75e, 0x7ae, 0x684, 0x690, 0x69c, 0x18EB
};//两个辅助函数声明
uint16_t calculate_code128_checksum(const char* input_string,uint32_t code128_length);
int strchr_temp(const char* str, int c);// 根据输入字符串自动选择Code 128字符集并生成编码数据
void generate_code128_auto(const char* input_string, uint16_t* code128_data, uint32_t* code128_length) {// 使用Code 128 B字符集编码code128_data[0] = 0x690; // Code 128起始码B*code128_length = 1;// 生成Code 128编码数据for (size_t i = 0; i < strlen(input_string); i++) {code128_data[*code128_length] = s_code128_encode_set[strchr_temp(code128_charset_B, input_string[i])];(*code128_length)++;}// 添加Code 128校验位code128_data[*code128_length] = calculate_code128_checksum(input_string, *code128_length);(*code128_length)++;// 添加Code 128停止码code128_data[*code128_length] = 0x18EB; // Code 128停止码(*code128_length)++;}// 计算Code 128字符的校验位
uint16_t calculate_code128_checksum(const char* input_string,uint32_t code128_length) {uint32_t sum = 104; // 初始校验和为第一个字符的值for (uint32_t i = 1; i <= code128_length; i++) {// 权重为字符在编码中的位置sum += i * strchr_temp(code128_charset_B, input_string[i-1]); }return sum % 103; // 对校验和取模
}int strchr_temp(const char* str, int c) {int temp = 0;while (*str != '\0') {if (*str == c) {return temp;//返回ID}str++;temp++;}return NULL;
}
<3>LVGL绘图函数实现
CODE128B算法实现之后,就可以把这个算法当成一个黑箱。作为使用者,我们只需要关心这个黑箱
的输入输出端口即可:输入一个字符串,输出一个0或者1告诉我们是画黑线条还是白线条。而有
了这个输出,就可以适配到LVGL上,我们只需要在LVGL画出相应的黑条或者白条即可。
void draw_blackbar(uint32_t code128to01_length,int x ,int y,uint32_t width,uint32_t height){lv_obj_t *rect = lv_obj_create(lv_scr_act()); // 创建一个矩形对象lv_obj_set_size(rect, width/code128to01_length, height); // 设置矩形的尺寸lv_obj_set_pos(rect, x, y);static lv_style_t style_rect; //创建样式lv_style_init(&style_rect); //初始化样式lv_style_set_bg_color(&style_rect,lv_color_black()); //设置背景颜色lv_style_set_radius(&style_rect,0); //设置圆角lv_obj_add_style(rect,&style_rect,LV_PART_MAIN); //添加样式lv_style_set_border_color(&style_rect,lv_color_black());//设置边框背景颜色
}void draw_whilebar(uint32_t code128to01_length,int x ,int y,uint32_t width,uint32_t height){lv_obj_t *rect = lv_obj_create(lv_scr_act()); // 创建一个矩形对象lv_obj_set_size(rect, width/code128to01_length, height); // 设置矩形的尺寸lv_obj_set_pos(rect, x, y);static lv_style_t style_rect;//加静态,这样它就只能被初始化一次,并且一直持续到程序结束为止。lv_style_init(&style_rect); //初始化样式lv_style_set_bg_color(&style_rect,lv_color_white()); //设置背景颜色lv_style_set_radius(&style_rect,0); //设置圆角lv_obj_add_style(rect,&style_rect,LV_PART_MAIN); //添加样式lv_style_set_border_color(&style_rect,lv_color_white());//设置边框背景颜色
}
//有聪明的靓仔肯定会问,这两玩意不是重复了吗?明明更新个color参数就行了。
//回答:我这边发现使用样式时会出BUG,所以暂时用这种冗余的做法,后面有时间再优化void draw_barcode(uint16_t* code128_data,uint32_t code128_length) {int xCoord = 46;int yCoord = 60;int code128_width = 270;int code128to01_length = (code128_length * 11)+1;int unitwidth = code128_width/code128to01_length;
// int unitwidth = 5;for (size_t i = 0; i < code128_length; i++) {int init_temp = (i == (code128_length-1)?11:10);for(int j = init_temp; j>=0 ; j--){if (((code128_data[i]>>j) & 1)== 1) {//printf("1");draw_blackbar(code128to01_length,xCoord,yCoord,code128_width,100); // 黑色条纹} else {//printf("0");draw_whilebar(code128to01_length,xCoord,yCoord,code128_width,100); // 白色条纹}xCoord +=unitwidth;}}printf("\n");
}int main(){lv_obj_clean(lv_scr_act()); //先清除UI,防止唤醒后再次初始化UI导致帧率变小const char* input_string = "Hello";uint32_t code128_length = 0;generate_code128_auto(input_string, code128_data, &code128_length);draw_barcode(code128_data,code128_length);
}
#附效果图
<4>ChatGPT使用有感
整个使用过程总体而言还是相当Nice的,比如:<1>可以直接让他把算法实现出来,直接让它把移植
代码写出来。尽管它写的代码不可能立即拿来使用,但是整体大框架是没有问题,我们可以依据这个
大框架,再根据自己的软硬件环境,做小的修改调整。(注意它写的代码还带有不少中文注释,这点
对于我们阅读也有非常大的作用)
<2>网上有C#实现的条形码算法,我是看不懂的,于是可以直接让Chatgpt翻译成C语言,我当时觉得
这个功能实在是太棒了!
总体而言,瑕不掩瑜,是个拥有极强信息过滤能力和代码编写能力,以及归纳总结能力的好帮手。