前面的文章《如何用c代码生成二维码》中已经介绍过了libzint开源库,我们也见识到了它的便捷性。本文将以如何生成一维码为核心,浅谈其他的实现方式和代码技巧。
《如何用c代码生成二维码》文章中已经介绍了,我们通过自行封装zint开源库处理的接口函数如下:
/****************************************************************************descpribe: create qrcode api with c code by calling zint lib.input : pqrcodedata, the qrcode data buf qrcodelen, the len of qrcode data, but it can be 0 pqrcodefile, the output file name of qrcode, it can be null output : pzintret, to store the ret code from linzint.return : 0 is ok, and other values are fail. see the meanings in enum zint_ret_codenotes : pqrcodefile, must end in .png, .eps or .svg. when isn,t null string.****************************************************************************/zint_ret_code zint_create_qrcode(uint8_t *pqrcodedata, int qrcodelen, char *pqrcodefile, int *pzintret); 类似地,我们生成一维码的接口函数也相近,如下所示:
/****************************************************************************descpribe: create barcode api with c code by calling zint lib.input : pbarcodedata, the barcode data buf barcodelen, the len of barcode data, but it can be 0 pbarcodefile, the output file name of barcode, it can be null output : pzintret, to store the ret code from linzint.return : 0 is ok, and other values are fail. see the meanings in enum zint_ret_codenotes : pbarcodefile, must end in .png, .eps or .svg. when isn,t null string.****************************************************************************/zint_ret_code zint_create_barcode(uint8_t *pbarcodedata, int barcodelen, char *pbarcodefile, int *pzintret); 两者几乎是一个模板刻出来的,可想而知,其内部实现,自然也是逻辑都是差不多的,都是调用到libzint中的:
zint_extern struct zint_symbol* zbarcode_create(void);zint_extern void zbarcode_clear(struct zint_symbol *symbol);zint_extern void zbarcode_delete(struct zint_symbol *symbol);zint_extern int zbarcode_encode_and_print(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle); 等等函数。于是,我们就在想,可以把调用libzint库中的函数封装成一个共用的功能函数,然后生成一维码和生产二维码的函数都通过传不同的参数进去,让这个共用的功能函数走不同case就可以完成相应的功能了。于是我们开始改造zint_code.c,将这个功能函数提出取出来,命名为 zint_ret_code zint_create_code_file(str_zint_code *zintcodeobj);
通过这个功能函数的入口,我们可以知道,我们定义了一个str_zint_code结构体,里面的成员变量如下所列:
typedef struct{ uint8_t *pcodedata; int codelen; char *pcodefile; code_type codetype; int maxcodelen; int *pzintret;}str_zint_code; //struct for create code file 这样我们就可以通过入参控制zint_create_code_file函数来执行不同的生成功能了。
以下是改造后的zint_code.c和zint_code.h
/**************************************************************************** * file : zint_code.c * * copyright (c) 2011 by li.recan * * description: demo for creating qrcode by c code. * * modification history * -------------------------------------------------------------------------- * date version author history * -------------------------------------------------------------------------- * 2016-10-15 1.0.0 li.recan written ***************************************************************************/ // standard library#include #include // so library#include zint.h// project header#include zint_code.h/****************************************************************************descpribe: create code file api with c code by calling zint lib. it's a common api for create barcode or qrcode.input : zintcodeobj, the zint create code file object output : zintcodeobj, the zint create code file object return : 0 is ok, and other values are fail. see the meanings in enum zint_ret_codenotes : null****************************************************************************/zint_ret_code zint_create_code_file(str_zint_code *zintcodeobj){ struct zint_symbol *pmysymbol = null; int retcode = 0; int codetypein = 0; if(!zintcodeobj) //check input pointer { return zint_err_inv_data; } //check code type if(zint_barcode == zintcodeobj->codetype) { codetypein = barcode_code128; } else if(zint_qrcode == zintcodeobj->codetype) { codetypein = barcode_qrcode; } if(zintcodeobj->codelen == 0) { zintcodeobj->codelen = strlen((char *)zintcodeobj->pcodedata); } if(zintcodeobj->codelen > zintcodeobj->maxcodelen)//len is too long { return zint_err_too_long; } if(0 == zbarcode_validid(codetypein)) { return zint_err_inv_code_id; } pmysymbol = zbarcode_create(); if(pmysymbol == null) { return zint_err_memory; } if(zintcodeobj->pcodefile)//when it's null, outfile will be out.png { if(strstr(zintcodeobj->pcodefile, png) || (strstr(zintcodeobj->pcodefile, eps)) || (strstr(zintcodeobj->pcodefile, svg))) { strcpy(pmysymbol->outfile, zintcodeobj->pcodefile); } else { zbarcode_clear(pmysymbol); zbarcode_delete(pmysymbol); //release memory in zint lib return zint_err_file_name; } } pmysymbol->symbology = codetypein; if(barcode_qrcode == codetypein) // special for qrcode { pmysymbol->option_1 = 3; //ecc level.it can be large when ecc level is larger.(value:1-4) pmysymbol->scale = 4; //contorl qrcode file size, default is 1, used to be 4 } pmysymbol->border_width = 2; //set white space width around your qrcode and 0 is for nothing retcode = zbarcode_encode_and_print(pmysymbol, zintcodeobj->pcodedata, zintcodeobj->codelen, 0); zbarcode_clear(pmysymbol); zbarcode_delete(pmysymbol); //release memory in zint lib if(zintcodeobj->pzintret) { *(zintcodeobj->pzintret) = retcode; //save ret code from zint lib } return ((0 == retcode) ? (zint_ok) : (zint_err_lib_ret));}/****************************************************************************descpribe: create barcode api with c code by calling zint lib.input : pbarcodedata, the barcode data buf barcodelen, the len of barcode data, but it can be 0 pbarcodefile, the output file name of barcode, it can be null output : pzintret, to store the ret code from linzint. return : 0 is ok, and other values are fail. see the meanings in enum zint_ret_codenotes : pbarcodefile, must end in .png, .eps or .svg. when isn,t null string.****************************************************************************/zint_ret_code zint_create_barcode(uint8_t *pbarcodedata, int barcodelen, char *pbarcodefile, int *pzintret){ str_zint_code zintcodeobj; memset(&zintcodeobj, 0, sizeof(str_zint_code)); zintcodeobj.pcodedata = pbarcodedata; zintcodeobj.codelen = barcodelen; zintcodeobj.pcodefile = pbarcodefile; zintcodeobj.pzintret = pzintret; zintcodeobj.codetype = zint_barcode; zintcodeobj.maxcodelen = barcode_max_len; return zint_create_code_file(&zintcodeobj);}/****************************************************************************descpribe: create qrcode api with c code by calling zint lib.input : pqrcodedata, the qrcode data buf qrcodelen, the len of qrcode data, but it can be 0 pqrcodefile, the output file name of qrcode, it can be null output : pzintret, to store the ret code from linzint. return : 0 is ok, and other values are fail. see the meanings in enum zint_ret_codenotes : pqrcodefile, must end in .png, .eps or .svg. when isn,t null string.****************************************************************************/zint_ret_code zint_create_qrcode(uint8_t *pqrcodedata, int qrcodelen, char *pqrcodefile, int *pzintret){ str_zint_code zintcodeobj; memset(&zintcodeobj, 0, sizeof(str_zint_code)); zintcodeobj.pcodedata = pqrcodedata; zintcodeobj.codelen = qrcodelen; zintcodeobj.pcodefile = pqrcodefile; zintcodeobj.pzintret = pzintret; zintcodeobj.codetype = zint_qrcode; zintcodeobj.maxcodelen = qrcode_max_len; return zint_create_code_file(&zintcodeobj);}/**************************************************************************** * file : zint_code.h * * copyright (c) 2011 by li.recan * * description: api for creating qrcode by c code. * * modification history * -------------------------------------------------------------------------- * date version author history * -------------------------------------------------------------------------- * 2016-10-15 1.0.0 li.recan written ***************************************************************************/ #ifndef __zint_code__#define __zint_code__#ifdef __cplusplusextern c{#endif#include #define qrcode_max_len 500 //max string len for creating qrcode#define barcode_max_len 100 //max string len for creating barcodetypedef enum { zint_ok = 0, zint_err_inv_data = -1, //input invalid data zint_err_too_long = -2, //len for input data is too long zint_err_inv_code_id = -3,//the code type is not supported by zint zint_err_memory = -4, //malloc memory error in zint lib zint_err_file_name = -5, //qrcode file isn'y end in .png, .eps or .svg. zint_err_lib_ret = -6, //zint lib ret error, real ret code should be zint api ret code}zint_ret_code;typedef enum{ zint_barcode = 1, //barcode type zint_qrcode = 2, //qrcode type}code_type;typedef struct{ uint8_t *pcodedata; int codelen; char *pcodefile; code_type codetype; int maxcodelen; int *pzintret;}str_zint_code; //struct for create code file/****************************************************************************descpribe: create barcode api with c code by calling zint lib.input : pbarcodedata, the barcode data buf barcodelen, the len of barcode data, but it can be 0 pbarcodefile, the output file name of barcode, it can be null output : pzintret, to store the ret code from linzint. return : 0 is ok, and other values are fail. see the meanings in enum zint_ret_codenotes : pbarcodefile, must end in .png, .eps or .svg. when isn,t null string.****************************************************************************/zint_ret_code zint_create_barcode(uint8_t *pbarcodedata, int barcodelen, char *pbarcodefile, int *pzintret);/****************************************************************************descpribe: create qrcode api with c code by calling zint lib.input : pqrcodedata, the qrcode data buf qrcodelen, the len of qrcode data, but it can be 0 pqrcodefile, the output file name of qrcode, it can be null output : pzintret, to store the ret code from linzint. return : 0 is ok, and other values are fail. see the meanings in enum zint_ret_codenotes : pqrcodefile, must end in .png, .eps or .svg. when isn,t null string.****************************************************************************/zint_ret_code zint_create_qrcode(uint8_t *pqrcodedata, int qrcodelen, char *pqrcodefile, int *pzintret);#define debuging(fmt, arg...) printf([%20s, %4d] fmt, __file__, __line__, ##arg)#ifdef __cplusplus}#endif#endif /* __zint_code__ */ 下面我们通过一个demo程序来验证下接口函数,即qrcode_test.c源程序,以下为其全部内容。
/**************************************************************************** * file : qrcode_test.c * * copyright (c) 2011 by li.recan * * description: demo for creating qrcode by c code. * * modification history * -------------------------------------------------------------------------- * date version author history * -------------------------------------------------------------------------- * 2016-10-15 1.0.0 li.recan written ***************************************************************************/ // standard library#include // project header#include zint_code.hint main(int argc, char *argv[]){ int zintlibret = 0; //ret code from zint lib zint_ret_code zintret = 0; //ret code from zint_code api char qrcodedata[] = i love zint lib. 测试一下gbk编码 ...; char qrcodedatadef[] = this's default qrcode file name : out.png ; char qrcodefile[] = myqrcode.png; // must end in .png, .eps or .svg. //zint lib ask ! char barcodedata[] = 13430931801; //barcode string char barcodefile[] = mybarcode.png; //test with inputing qrcode_file name zintret = zint_create_qrcode((uint8_t*)qrcodedata, 0, qrcodefile, &zintlibret); if(zint_ok != zintret) { debuging(create qrcode err, zintret = %d, zintlibret = %d\n, zintret, zintlibret); } else { debuging(create qrcode ok ! \nview qrcode file : %s in cur path. zintret = %d, zintlibret = %d\n, qrcodefile, zintret, zintlibret); } //test without inputing qrcode_file name zintret = zint_create_qrcode((uint8_t*)qrcodedatadef, 0, null, &zintlibret); if(zint_ok != zintret) { debuging(create qrcode err, zintret = %d, zintlibret = %d\n, zintret, zintlibret); } else { debuging(create qrcode ok ! \nview qrcode file : out.png in cur path. zintret = %d, zintlibret = %d\n, zintret, zintlibret); } //test create barcode with name mybarcode.png zintret = zint_create_barcode((uint8_t*)barcodedata, 0, barcodefile, &zintlibret); if(zint_ok != zintret) { debuging(create barcode err, zintret = %d, zintlibret = %d\n, zintret, zintlibret); } else { debuging(create barcode ok ! \nview barcode file : %s in cur path. zintret = %d, zintlibret = %d\n, barcodefile, zintret, zintlibret); } return 0;} 前半部分还是保留上一次测试生产二维码的代码;而新增了生成一维码的测试代码。
编辑
之后再运行demo程序,如下:
如框框所示,即为成功运行程序,生成的一维码图片。它的展示如下:
用微信等扫一扫工具,扫描结果如下:
结果正如我们代码所写,证明程序执行是没有问题的。
好了,本期如何用c代码生成一维码就介绍到这里了。有兴趣的童鞋可以私下联系,互相学习。
无人机赴震区勘查灾情
嵌入式硬件电路设计方面的几个注意事项
光栅尺编码器差分信号脉冲计数采集模块/频率可达5MHz/4倍频计数
移远通信与哈啰出行合作获奖 美光提供176层NAND数据中心SSD
虹科分享|虹科Dimetix激光测距传感器如何利用反射来测量?(下)
【C语言应用】如何用C代码生成一维码?
大联大世平集团推出基于NXP产品的PEPS无钥匙进入及启动系统方案
区块链会对房地产领域产生什么影响
4G/5G园区网络常见的受损核心网络攻击情形 5G智慧园区十大应用场景
vlookup过来的数据怎么变成文本
otl功率放大器实验报告
5G网络技术是把双刃剑,网络安全问题需重视
百度对Robin第一时间做出回答:我没说过
Android终端搭建kali渗透测试环境
全球首届无人机世锦赛在深圳隆重开幕
请问FPGA数字IO如何实现DAC功能呢?
XeSS加持、驱动更新带来革新体验,深度测评英特尔锐炫A750
2023年中国台湾IC产值将下降12.7%至4.22万亿元新台币
华为今天下午发布会 华为非凡大师之HUAWEI WATCH
如何制作自己的颤音效果踏板