(Chatgpt辅助)C语言移植Code128B条形码算法到LVGL8.3【附跑通代码】

(Chatgpt辅助)C语言移植Code128B条形码算法到LVGL8.3【附跑通代码】


序言:
这篇博客是我在移植条形码过程中,发现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语言,我当时觉得

这个功能实在是太棒了!

总体而言,瑕不掩瑜,是个拥有极强信息过滤能力和代码编写能力,以及归纳总结能力的好帮手。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值