如何用C代码生成二维码

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

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

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

  在介绍如何用代码生成二维码之前,就不得不先介绍一个开源库叫zint。这个开源可谓牛叉的很,几乎平时见过的“码”,各式各样的一维条码、各式各样的二维码条码都难不倒它,重要的是,它还是开源的,几乎包含了所有常见“码”的生成。以下是摘自官方用户使用手册的介绍片段。(笔者上一篇博文介绍zint的安装时简单介绍了一下zint库,http://www.cnblogs.com/Recan/p/5967378.html ,它的开源项目网页为https://sourceforge.net/projects/zint/)

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 <string.h>
17 #include <stdio.h>
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 <stdint.h>
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__ */

View Code: zint_code.h

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

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

 1 /****************************************************************************
 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 <stdio.h>
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 }

View Code: qrcode_test.c

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

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

  

  那么赶紧回到上一篇博文 http://www.cnblogs.com/Recan/p/5967378.html 把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。

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

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

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

    

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

证明这代码是可行的。

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

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

转载于:https://www.cnblogs.com/Recan/p/5967673.html

如何用C代码生成二维码相关推荐

  1. Java实现一行代码生成二维码,可传输到前端展示,可自定义二维码样式,可设置图片格式,可对二维码添加图片,可对二维码添加文字,可以设置二维码大小、字体大小、字体颜色、边框颜色、边框大小等等

    Java实现一行代码生成二维码,可传输到前端展示,可自定义二维码样式,可设置图片格式,可对二维码添加图片,可对二维码添加文字,可以设置二维码大小.字体大小.字体颜色.边框颜色.边框大小等等. 0.准备 ...

  2. Java代码生成二维码

    Java代码生成二维码: 背景:在项目的需求中,大部分会需要你写一个生成二维码的功能,二维码里面存储特定的信息 示例: pom.xml依赖: <!-- Zxing--><depend ...

  3. 如何用手机扫二维码盘点海量固定资产?

    今天跟大家分享如何用手机去快速地盘点海量固定资产. 第一步,将固定资产批量导入到易点易动固定资产管理系统中后,选择一个二维码或条形码的标签模板,将固定资产标签批量打印出来,贴到对应的固定资产上. 第二 ...

  4. 如何用MediaCapture解决二维码扫描问题

    二维码扫描的实现,简单的来说可以分三步走:"成像"."截图"与"识别". UWP开发中,最常用的媒体工具非MediaCapture莫属了,下 ...

  5. C# 代码生成二维码方法及代码示例(QRCoder)

    背景 二维码是越来越流行了,很多地方都有可能是使用到.如果是静态的二维码还是比较好处理的,通过在线工具就可以直接生成一张二维码图片,比如:草料二维码.但有的时候是需要动态生成的(根据动态数据生成),这 ...

  6. 如何用Python生成二维码

    使用Python做二维码需要一个非常简单的模块--MyQR,这个模块相比于QRcode更加简单,功能也是特别强大,下面介绍一种生成简单二维码的方式. 安装方式 利用pip安装. 使用方式 首先导入. ...

  7. 如何用java制作二维码

    首先:进入这个网址 github.com/zxing/. 将他复制成功后,就让他导出 就成这样啦 然后就新建个项目把刚才的包导入新建的项目 就像这样 接下来开始进行包的配置 . 这样大部分就弄完啦 接 ...

  8. 如何用python做二维码识别软件_Python什么都能做(一)用 Python 做一个扫码工具...

    Python实现扫码工具 二维码作为一种信息传递的工具,在当今社会发挥了重要作用.从手机用户登录到手机支付,生活的各个角落都能看到二维码的存在.那你知道二维码是怎么解析的吗?有想过自己实现一个扫码工具 ...

  9. 一句代码生成二维码,一句代码生成条形码,批量生成二维码和条形码,步骤教学

    生产企业或者物流快递需要用到大量的二维码和条形码,但是要自行编写代码批量生成二维码或者条形码并不容易,涉及的知识面很广. Excel插件<E灵>提供了二维码接口和条形码接口,您只需要一句代 ...

最新文章

  1. windows错误:Failed to import pydot. You must install pydot and graphviz for `pydotprint` to work.
  2. Ubuntu 10.04编译安装CodeBlocks 10.5
  3. js中获取事件对象的方法小结
  4. Kubernetes理论基础
  5. 哪吒之魔童降世视听语言影评_国漫神作 再造辉煌——《哪吒之魔童降世》影评...
  6. php 内容转换dom,php – 防止DOMDocument :: loadHTML()转换实体
  7. 最新,Python终成第1!Java和C长期霸榜时代结束
  8. 人工智能切入垂直领域 风口已至?
  9. 昆仑通态如何连接sqlserver数据库_三菱FX5U 与昆仑通态触摸屏的连接操作步骤
  10. CentOS配置snmp
  11. 正轴等角割圆锥投影综述
  12. UI设计师的7大能力模型
  13. Python编程之求累乘和
  14. 远程桌面 服务器握手,《易语言远程控制技术教程》第2课_远程桌面(你的桌面我作主)王军...
  15. Autodesk ReCap-现实捕获技术
  16. 使用excel公式vlookup提取多个表中的数据
  17. 老罗(www.luocong.com)
  18. dplayer解析源码php调用,从demo分析ijk源码一:视频播放
  19. Hbase2.4.9学习
  20. 基于CTC转换器的自动拼写校正端到端语音识别

热门文章

  1. 网易自动化UI测试解决方案Airtest Project亮相GDC
  2. Java应用程序与小程序之间有那些差别?
  3. ORA-01123:无法启动联机备份;未启用介质恢复(错误分析)
  4. golang 防知乎 中文验证码 源码
  5. angularJs-脏检查
  6. Core Java笔记 6.部署应用程序
  7. C#嵌套任务和子任务
  8. Java持久性API(JPA)第7讲——实体生命周期及生命周期回调方法
  9. android 单例的作用,Android中单例模式的几个坑
  10. aliplayer 手机全屏控件不显示_Flutter 强大的MediaQuery控件