0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【C语言应用】如何用C代码生成二维码?

嵌入式物联网开发 来源:嵌入式物联网开发 作者:嵌入式物联网开发 2022-08-24 19:01 次阅读

当下因微信和支付宝等手机应用广泛使用,而基于二维码/一维条码的移动支付,也借助手机移动端席卷全国,使得越来越多的人知道有“二维码”这么一种东西。

对于普通用户而来,一般只知道将自己的二维码展示给别人,别人使用软件识别这个二维码即可完成一定的功能。比如,扫码二维码付款、扫码二维码加微信好友、扫码二维码访问网页、扫码二维码下载app等等。这些个功能,在日常行为中,已经很常见了,但作为程序猿的我们,我们怎么能不知道二维码是如何生成的呢?或者说,我要自己生成一个二维码,除了去网页上找二维码生成工具来生成,我可以自己编码来实现么?

答案,当然是,必须可以。不然这文章不用写了。

在介绍如何用代码生成二维码之前,就不得不先介绍一个开源库叫zint。这个开源可谓牛叉的很,几乎平时见过的“码”,各式各样的一维条码、各式各样的二维码条码都难不倒它,重要的是,它还是开源的,几乎包含了所有常见“码”的生成。以下是摘自官方用户使用手册的介绍片段。(笔者上一篇博文介绍zint的安装时简单介绍了一下zint库,如何在linux平台安装zint开源库 - 架构师李肯 - 博客园,它的开源项目网页为Zint Barcode Generator download | SourceForge.net)

The Zint project aims to provide a complete cross-platform open source barcode generating solution. The package currently consists of a Qt based GUI, a command line executable and a library with an API to allow developers access to the capabilities of Zint. It is hoped that Zint provides a solution which is flexible enough for professional users while at the same time takes care of as much of the processing as possible to allow easy translation from input data to barcode image.

-----------------------------------------------------华丽丽的分割线-----------------------------------------------------

言归正传,说回如何使用zint库生成二维码。主要使用到以下几个函数:可以从zint.h中得到api的声明(主要是C语言接口)。

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);

以下是个人封装的生成二维码的自定义接口函数:

/****************************************************************************

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_CODE

Notes : 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);

这个接口定义比较简单,上面也简单说了各个参数的意义,其他中特别需要注意的是,如果传入生成二维码图片名字不使用默认值时(pQrCodeFile != NULL),也务必保证pQrCodeFile必须是以.png, .eps or .svg.结尾的文件名。

以下是zint_code.c 和 zint_code.h的内容,里面将zint中生成二维码的几个函数封装在一块了,使用者只需关注上面定义的Zint_Create_QrCode函数,即可生成漂亮的二维码图片文件。

 ​




 1 /****************************************************************************
 2  * File       : zint_code.c
 3  * 
 4  * Copyright (c) 2011 by Li.Recan < 721317716@qq.com >
 5  * 
 6  * DESCRIPTION: Demo for creating qrcode by C code.
 7  * 
 8  * Modification history
 9  * --------------------------------------------------------------------------
10  * Date         Version  Author       History
11  * --------------------------------------------------------------------------
12  * 2016-10-15   1.0.0    Li.Recan     written
13  ***************************************************************************/
14  
15 // Standard Library
16 #include 
17 #include 
18 
19 // so Library
20 #include "zint.h"
21 
22 // Project Header
23 #include "zint_code.h"
24 
25 
26 /****************************************************************************
27 Descpribe: Create Qrcode API with C Code by calling zint lib.
28 Input    : pQrCodeData, the qrcode data buf
29            QrcodeLen, the len of qrcode data, but it can be 0
30            pQrCodeFile, the output file name of qrcode, it can be NULL           
31 Output   : pZintRet, to store the ret code from linzint. 
32 Return   : 0 is ok, and other values are fail. See the meanings in enum ZINT_RET_CODE
33 Notes    : pQrCodeFile, Must end in .png, .eps or .svg. when isn,t NULL string.
34 ****************************************************************************/
35 ZINT_RET_CODE Zint_Create_QrCode(uint8_t *pQrCodeData, int QrcodeLen, char *pQrCodeFile, int *pZintRet)
36 {
37     struct zint_symbol *pMySymbol     = NULL;
38     int RetCode                     = 0;    
39     
40     if(!pQrCodeData) //check input pointer
41     {
42         return ZINT_ERR_INV_DATA;
43     }
44 
45     if(QrcodeLen == 0)
46     {
47         QrcodeLen = strlen((char *)pQrCodeData);
48     }
49     if(QrcodeLen > QRCODE_MAX_LEN)//len is too long
50     {        
51         return ZINT_ERR_TOO_LONG;
52     }
53 
54     if(0 == ZBarcode_ValidID(BARCODE_QRCODE))
55     {
56         return ZINT_ERR_INV_CODE_ID;
57     }
58     
59     pMySymbol = ZBarcode_Create();
60     if(pMySymbol == NULL)
61     {
62         return ZINT_ERR_MEMORY;
63     }
64 
65     if(pQrCodeFile)//when it's NULL, outfile will be "out.png"
66     {
67         if(strstr(pQrCodeFile, "png") || (strstr(pQrCodeFile, "eps")) || (strstr(pQrCodeFile, "svg")))
68         {
69             strcpy(pMySymbol->outfile, pQrCodeFile);
70         }
71         else
72         {
73             ZBarcode_Clear(pMySymbol);
74             ZBarcode_Delete(pMySymbol); //release memory in zint lib
75             return ZINT_ERR_FILE_NAME;
76         }
77     }
78     pMySymbol->symbology     = BARCODE_QRCODE;  
79     pMySymbol->option_1     = 3; //ECC Level.It can be large when ECC Level is larger.(value:1-4)  
80     pMySymbol->scale         = 4; //contorl qrcode file size, default is 1, used to be 4   
81     pMySymbol->border_width = 2; //set white space width around your qrcode and 0 is for nothing 
82     
83     RetCode = ZBarcode_Encode_and_Print(pMySymbol, pQrCodeData, QrcodeLen, 0);    
84     ZBarcode_Clear(pMySymbol);
85     ZBarcode_Delete(pMySymbol); //release memory in zint lib
86 
87     if(pZintRet)
88     {
89         *pZintRet = RetCode; //save ret code from zint lib
90     }
91     
92     return ((0 == RetCode) ? (ZINT_OK) : (ZINT_ERR_LIB_RET));
93 }
View Code: zint_code.c




 1 /****************************************************************************
 2  * File       : zint_code.h
 3  * 
 4  * Copyright (c) 2011 by Li.Recan < 721317716@qq.com >
 5  * 
 6  * DESCRIPTION: API for creating qrcode by C code.
 7  * 
 8  * Modification history
 9  * --------------------------------------------------------------------------
10  * Date         Version  Author       History
11  * --------------------------------------------------------------------------
12  * 2016-10-15   1.0.0    Li.Recan     written
13  ***************************************************************************/
14  
15 #ifndef __ZINT_CODE__
16 #define __ZINT_CODE__
17 
18 #ifdef __cplusplus
19 extern "C"
20 {
21 #endif
22 
23 #include 
24 
25 #define QRCODE_MAX_LEN        500 //max string len for creating qrcode
26 
27 typedef enum 
28 {
29     ZINT_OK                 = 0,
30     ZINT_ERR_INV_DATA         = -1, //input invalid data
31     ZINT_ERR_TOO_LONG         = -2, //len for input data is too long    
32     ZINT_ERR_INV_CODE_ID     = -3,//the code type is not supported by zint
33     ZINT_ERR_MEMORY         = -4, //malloc memory error in zint lib
34     ZINT_ERR_FILE_NAME        = -5, //qrcode file isn'y end in .png, .eps or .svg.
35     ZINT_ERR_LIB_RET         = -6, //zint lib ret error, real ret code should be zint api ret code
36 }ZINT_RET_CODE;
37 
38 /****************************************************************************
39 Descpribe: Create Qrcode API with C Code by calling zint lib.
40 Input    : pQrCodeData, the qrcode data buf
41            QrcodeLen, the len of qrcode data, but it can be 0
42            pQrCodeFile, the output file name of qrcode, it can be NULL           
43 Output   : pZintRet, to store the ret code from linzint. 
44 Return   : 0 is ok, and other values are fail. See the meanings in enum ZINT_RET_CODE
45 Notes    : pQrCodeFile, Must end in .png, .eps or .svg. when isn,t NULL string.
46 ****************************************************************************/
47 ZINT_RET_CODE Zint_Create_QrCode(uint8_t *pQrCodeData, int QrcodeLen, char *pQrCodeFile, int *pZintRet);
48 
49 #define Debuging(fmt, arg...)       printf("[%20s, %4d] "fmt, __FILE__, __LINE__, ##arg)
50 
51 #ifdef __cplusplus
52 }
53 #endif
54 
55 #endif /* __ZINT_CODE__ */
​

在工程实践中,只需要将这两个文件添加到工程中,并让他们参与工程编译,即可完美使用zint生成二维码了。

下面是一个简单的demo,将会展示如何使用这个接口函数,见qrcode_test.c

/****************************************************************************
 2  * File       : qrcode_test.c
 3  * 
 4  * Copyright (c) 2011 by Li.Recan < 721317716@qq.com >
 5  * 
 6  * DESCRIPTION: Demo for creating qrcode by C code.
 7  * 
 8  * Modification history
 9  * --------------------------------------------------------------------------
10  * Date         Version  Author       History
11  * --------------------------------------------------------------------------
12  * 2016-10-15   1.0.0    Li.Recan     written
13  ***************************************************************************/
14  
15 // Standard Library
16 #include 
17 
18 // Project Header
19 #include "zint_code.h"
20 
21 int main(int argc, char *argv[])
22 {
23     int ZintLibRet             = 0; //ret code from zint lib
24     ZINT_RET_CODE ZintRet     = 0; //ret code from zint_code api
25     char QrcodeData[]         = "I love zint lib. 测试一下gbk编码 ...";
26     char QrcodeDataDef[]     = "This's default qrcode file name : out.png ";
27     char QrcodeFile[]         = "MyQrcode.png"; // Must end in .png, .eps or .svg. //zint lib ask !
28     
29     //test with inputing qrcode_file name
30     ZintRet = Zint_Create_QrCode((uint8_t*)QrcodeData, 0, QrcodeFile, &ZintLibRet);
31     if(ZINT_OK != ZintRet)
32     {
33         Debuging("Create qrcode err, ZintRet = %d, ZintLibRet = %d\n", ZintRet, ZintLibRet);
34     }
35     else
36     {
37         Debuging("Create qrcode OK ! View qrcode file : %s in cur path. ZintRet = %d, ZintLibRet = %d\n", QrcodeFile, ZintRet, ZintLibRet);
38     }
39     
40     //test without inputing qrcode_file name
41     ZintRet = Zint_Create_QrCode((uint8_t*)QrcodeDataDef, 0, NULL, &ZintLibRet);
42     if(ZINT_OK != ZintRet)
43     {
44         Debuging("Create qrcode err, ZintRet = %d, ZintLibRet = %d\n", ZintRet, ZintLibRet);
45     }
46     else
47     {
48         Debuging("Create qrcode OK ! View qrcode file : out.png in cur path. ZintRet = %d, ZintLibRet = %d\n", ZintRet, ZintLibRet);
49     }
50     
51     return 0;
52 }

输入完成后,使用gcc -o qrcode_test qrcode_test.c zint_code.c –lzint 即可编译出qrcode_test的bin文件了。

等等,如果你的linux还未安装zint库,sorry,你将看到

那么赶紧回到上一篇博文 如何在linux平台安装zint开源库 - 架构师李肯 - 博客园 把zint安装起来吧。

准确无误的编译,之后,在当前目录ls就可以看到qrcode_test的bin文件了。

我们使用./ qrcode_test运行我们编译出来的demo程序,可以看到以下的提示:

[liluchang@localhost src]$ ./qrcode_test

./qrcode_test: error while loading shared libraries: libzint.so.2.4: cannot

open shared object file: No such file or directory

又出什么问题了,原来系统在运行这个demo程序时,没有找到libzint.so来链接,那么我们只需要在运行之前告诉系统去哪里找这个so即可。使用

export LD_LIBRARY_PATH=/usr/local/lib 这个路径是根据情况而定的。【注意这个export只对当前运行的shell生效,一旦切换一个shell,则需要重新输入。如果需要固定告诉运行demo的时候去哪里找so链接,则可以在编译的时候告诉它。这个点往后再介绍。】

之后再运行demo程序:

第一个框框里面是demo程序打印出来的调试信息,标识连个二维码都生成成功了。

第二个框框可以看到,在当前目录下,就已经生成了这两个png文件,并且第二个生成的使用的是系统默认的名字out.png。

为了验证程序生成的二维码是否正确,我们可以使用手机去扫码一下这两个二维码:

为了验证程序生成的二维码是否正确,我们可以使用手机去扫码一下这两个二维码:

用手机扫描出来的结果如下:

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

​编辑

图中显示的扫描结果,正好如demo中写的

证明这代码是可行的。

好了,本篇介绍使用C语言调用zint库生成二维码的教程就介绍到这里。感兴趣的童鞋可以评论留言或者自行阅读zint用户手册或开源项目介绍网页详细内容。

后话,下篇文章将介绍zint库一维条码的生成,敬请期待。届时,zint_code.c的接口又丰富一些了。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7618

    浏览量

    138678
收藏 人收藏

    评论

    相关推荐

    一“”当先!看二维码模组如何重塑智能门锁扫体验

    在科技日新月异的今天,智能门锁正逐步取代传统机械锁,成为现代家庭安全防护的首选。在这场门锁智能化革命中,二维码模组以其独特的识别技术和便捷的操作方式,成为智能门锁的重要组成部分。本文将深入探讨二维码
    的头像 发表于 03-12 16:17 59次阅读
    一“<b class='flag-5'>码</b>”当先!看<b class='flag-5'>二维码</b>模组如何重塑智能门锁扫<b class='flag-5'>码</b>体验

    嵌入式二维码识别引擎是什么设备?哪些场景用得到?

    在科技日新月异的今天,嵌入式技术已广泛渗透到我们生活的方方面面,其中,嵌入式二维码识别引擎作为一种高效、便捷的信息采集工具,正逐渐成为众多行业智能化升级的重要推手。本文将带您深入探索二维码识读引擎
    的头像 发表于 03-10 14:57 53次阅读
    嵌入式<b class='flag-5'>二维码</b>识别引擎是什么设备?哪些场景用得到?

    快速将二维码扫描识别模组嵌入集成到安卓一体机上使用

    在现代科技快速发展的今天,二维码扫描模组的应用已深入到各个行业领域。特别是在安卓一体机中,二维码扫描模组已成为其不可或缺的一部分。本文将详细介绍如何在安卓一体机上安装二维码扫描模组、连接二维码
    的头像 发表于 02-28 15:59 128次阅读
    快速将<b class='flag-5'>二维码</b>扫描识别模组嵌入集成到安卓一体机上使用

    工业级二维码扫描模组有哪些特点?

    工业级二维码扫描模组是用于各种工业环境中,快速、准确地识别和解码二维码的关键设备。随着工业4.0和物联网的快速发展,工业级二维码扫描模组的应用范围越来越广泛,成为了许多自动化和智能化生产线中不可或缺
    的头像 发表于 12-02 15:02 234次阅读
    工业级<b class='flag-5'>二维码</b>扫描模组有哪些特点?

    工业二维码器在电子制造业中的应用

    工业二维码器在电子制造业中的应用主要体现在以下几个方面:▲生产追溯管理工业二维码器通过对电子产品上的二维码进行快速扫描,实现了高效、
    的头像 发表于 11-13 16:19 316次阅读
    工业<b class='flag-5'>二维码</b>读<b class='flag-5'>码</b>器在电子制造业中的应用

    二维码识读设备有哪些类型

    随着二维码应用的日益普及,各类二维码识读设备也应运而生。这些设备不仅极大地方便了我们的日常生活,也为企业提供了更加高效便捷的服务。那么,你知道二维码识读设备都有哪些类型吗?让我们一起来了解一下。据
    的头像 发表于 11-05 16:10 466次阅读
    <b class='flag-5'>二维码</b>识读设备有哪些类型

    二维码扫描头设备嵌入到闸机上,实现扫手机屏幕完成签到签退

    在现代社会,随着科技的飞速发展,二维码技术已经渗透到我们生活的方方面面,特别是在门禁管理、签到签退等场景中,二维码扫描头设备的嵌入应用极大地提升了管理效率和用户体验。本文将探讨二维码扫描头设备
    的头像 发表于 09-18 15:45 447次阅读
    <b class='flag-5'>二维码</b>扫描头设备嵌入到闸机上,实现扫手机屏幕<b class='flag-5'>码</b>完成签到签退

    工业二维码扫描设备如何助力流水线生产?

    工业二维码扫描设备被广泛应用于现代工厂的流水线作业中,它们能够高效、准确地读取移动中的二维码。这些扫器通常被设计为固定式或手持式,以适应不同的生产环境和需求。固定式扫器安装在特定位
    的头像 发表于 08-12 14:56 443次阅读
    工业<b class='flag-5'>二维码</b>扫描设备如何助力流水线生产?

    如何为柜式终端设备选配(集成)二维码模块?

    随着二维码技术在各行各业的广泛应用,柜式终端设备如何高效集成二维码模块成为行业关注焦点。针对这一需求,本文将深入探讨选择与集成二维码模块的关键要素,助力企业精准匹配,提升终端设备性能。在柜式终端设备
    的头像 发表于 08-05 15:48 383次阅读
    如何为柜式终端设备选配(集成)<b class='flag-5'>二维码</b>模块?

    Labview生成二维码

     Labview 的一个Demo,生成二维码
    发表于 08-01 17:12 11次下载

    二维码器/二维码读取设备嵌入园区闸机系统中的应用

    二维码阅读设备集成至闸机系统中,主要功能是通过扫描用户的二维码通行证来实施园区出入口的自动收费。此技术凭借二维码的便利性及扫描设备的高效性,极大地提高了收费效率和精确度,减少了由于人为错误
    的头像 发表于 06-05 14:46 506次阅读
    <b class='flag-5'>二维码</b>扫<b class='flag-5'>码</b>器/<b class='flag-5'>二维码</b>读取设备嵌入园区闸机系统中的应用

    ELF 1技术贴|如何在开发板上生成二维码图像

    在开发应用程序时,常常需要生成二维码以便于用户通过扫描快速访问信息。为了实现这一功能开发者通常选用QRencode专为生成二维码图像设计的开源库。然而,要在特定平台上使用QRencod
    的头像 发表于 05-07 14:54 755次阅读
    ELF 1技术贴|如何在开发板上<b class='flag-5'>生成</b><b class='flag-5'>二维码</b>图像

    飞凌嵌入式ElfBoard ELF 1板卡-在线二维码生成

    在线二维码生成器允许用户将文本、网址、图片或其他数据转换为二维码形式。二维码是一种特殊类型的条形码,它可以通过扫描来快速识别和读取信息。在线二维码
    发表于 04-24 17:00

    怎么在Framewin里显示二维码

    各位前辈好,刚刚开始使用STemWin。现在一个Framewin里显示二维码,在Framewin初始化里调用二维码函数没有反应。请问需要怎么调用?
    发表于 04-16 08:27

    远距离二维码扫描器如何选择?看看以下三款远距离二维码模块

    随着二维码相关技术及硬件的普及与低成本化,二维条码扫描设备的应用被人们广为熟知,应用的行业也众多。然而,在某些场景中,由于需要远距离扫描二维码(条码远距离识别),传统的扫设备已经无法
    的头像 发表于 03-21 15:41 882次阅读
    远距离<b class='flag-5'>二维码</b>扫描器如何选择?看看以下三款远距离<b class='flag-5'>二维码</b>扫<b class='flag-5'>码</b>模块