如何用C代码生成二维码
如何用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函数,即可生成漂亮的二维码图片文件。
/****************************************************************************
* File : zint_code.c
*
* Copyright (c) 2011 by Li.Recan < 721317716@qq.com >
*
* 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 <string.h>
#include <stdio.h> // so Library
#include "zint.h" // Project Header
#include "zint_code.h" /****************************************************************************
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)
{
struct zint_symbol *pMySymbol = NULL;
int RetCode = ; if(!pQrCodeData) //check input pointer
{
return ZINT_ERR_INV_DATA;
} if(QrcodeLen == )
{
QrcodeLen = strlen((char *)pQrCodeData);
}
if(QrcodeLen > QRCODE_MAX_LEN)//len is too long
{
return ZINT_ERR_TOO_LONG;
} if( == ZBarcode_ValidID(BARCODE_QRCODE))
{
return ZINT_ERR_INV_CODE_ID;
} pMySymbol = ZBarcode_Create();
if(pMySymbol == NULL)
{
return ZINT_ERR_MEMORY;
} if(pQrCodeFile)//when it's NULL, outfile will be "out.png"
{
if(strstr(pQrCodeFile, "png") || (strstr(pQrCodeFile, "eps")) || (strstr(pQrCodeFile, "svg")))
{
strcpy(pMySymbol->outfile, pQrCodeFile);
}
else
{
ZBarcode_Clear(pMySymbol);
ZBarcode_Delete(pMySymbol); //release memory in zint lib
return ZINT_ERR_FILE_NAME;
}
}
pMySymbol->symbology = BARCODE_QRCODE;
pMySymbol->option_1 = ; //ECC Level.It can be large when ECC Level is larger.(value:1-4)
pMySymbol->scale = ; //contorl qrcode file size, default is 1, used to be 4
pMySymbol->border_width = ; //set white space width around your qrcode and 0 is for nothing RetCode = ZBarcode_Encode_and_Print(pMySymbol, pQrCodeData, QrcodeLen, );
ZBarcode_Clear(pMySymbol);
ZBarcode_Delete(pMySymbol); //release memory in zint lib if(pZintRet)
{
*pZintRet = RetCode; //save ret code from zint lib
} return (( == RetCode) ? (ZINT_OK) : (ZINT_ERR_LIB_RET));
}
: zint_code.c
/****************************************************************************
* File : zint_code.h
*
* Copyright (c) 2011 by Li.Recan < 721317716@qq.com >
*
* 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 __cplusplus
extern "C"
{
#endif #include <stdint.h> #define QRCODE_MAX_LEN 500 //max string len for creating qrcode typedef enum
{
ZINT_OK = ,
ZINT_ERR_INV_DATA = -, //input invalid data
ZINT_ERR_TOO_LONG = -, //len for input data is too long
ZINT_ERR_INV_CODE_ID = -,//the code type is not supported by zint
ZINT_ERR_MEMORY = -, //malloc memory error in zint lib
ZINT_ERR_FILE_NAME = -, //qrcode file isn'y end in .png, .eps or .svg.
ZINT_ERR_LIB_RET = -, //zint lib ret error, real ret code should be zint api ret code
}ZINT_RET_CODE; /****************************************************************************
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); #define Debuging(fmt, arg...) printf("[%20s, %4d] "fmt, __FILE__, __LINE__, ##arg) #ifdef __cplusplus
}
#endif #endif /* __ZINT_CODE__ */
: zint_code.h
在工程实践中,只需要将这两个文件添加到工程中,并让他们参与工程编译,即可完美使用zint生成二维码了。
下面是一个简单的demo,将会展示如何使用这个接口函数,见qrcode_test.c
/****************************************************************************
* File : qrcode_test.c
*
* Copyright (c) 2011 by Li.Recan < 721317716@qq.com >
*
* 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 <stdio.h> // Project Header
#include "zint_code.h" int main(int argc, char *argv[])
{
int ZintLibRet = ; //ret code from zint lib
ZINT_RET_CODE ZintRet = ; //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 ! //test with inputing qrcode_file name
ZintRet = Zint_Create_QrCode((uint8_t*)QrcodeData, , QrcodeFile, &ZintLibRet);
if(ZINT_OK != ZintRet)
{
Debuging("Create qrcode err, ZintRet = %d, ZintLibRet = %d\n", ZintRet, ZintLibRet);
}
else
{
Debuging("Create qrcode OK ! View 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, , NULL, &ZintLibRet);
if(ZINT_OK != ZintRet)
{
Debuging("Create qrcode err, ZintRet = %d, ZintLibRet = %d\n", ZintRet, ZintLibRet);
}
else
{
Debuging("Create qrcode OK ! View qrcode file : out.png in cur path. ZintRet = %d, ZintLibRet = %d\n", ZintRet, ZintLibRet);
} return ;
}
: 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的接口又丰富一些了。
如何用C代码生成二维码的更多相关文章
- 如何用.NET生成二维码?
二维码是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的,国外对二维码技术的研究始于20世纪80年代末,在二维码符号表示技术研究方面已研制出多种码制,常见的有P ...
- java代码生成二维码
java代码生成二维码一般步骤 常用的是Google的Zxing来生成二维码,生成的一般步骤如下: 一.下载zxing-core的jar包: 二.需要创建一个MatrixToImageWriter类, ...
- 如何用MediaCapture解决二维码扫描问题
二维码扫描的实现,简单的来说可以分三步走:“成像”.“截图”与“识别”. UWP开发中,最常用的媒体工具非MediaCapture莫属了,下面就来简单介绍一下如何利用MediaCapture来实现扫描 ...
- java代码生成二维码以及解析二维码
package com.test; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedI ...
- php代码生成二维码
//引用范例 1 public function index() { 2 echo "<img src='http://qr.liantu.com/api.php?bg=f3f3f3& ...
- 用c#开发微信 (20) 微信登录网站 - 扫描二维码登录
像京东,一号店等网站都实现了用微信来登录的功能,就是用手机上的微信扫一扫网站上的二维码,微信上确认后,即可自动用微信的帐号登录网站. 1 创建网站应用 在微信开放平台创建一个网站应用 https:// ...
- 通过jquery-qrcode在线生成二维码
随着移动互联网的发展,二维码现在应用得越来越广泛了,随手扫扫就可以浏览网站.加个好友什么的,比起手工输入真的是方便太多了. 前期做了一个综合测评系统,考虑逐步实现移动化,一长串的IP地址用户输入也不方 ...
- Asp.Net微信登录-电脑版扫描二维码登录
像京东,一号店等网站都实现了用微信来登录的功能,就是用手机上的微信扫一扫网站上的二维码,微信上确认后,即可自动用微信的帐号登录网站. 一.创建网站应用 在微信开放平台创建一个网站应用 https:// ...
- Android进阶笔记06:Android 实现扫描二维码实现网页登录
一. 扫描二维码登录的实现机制: 详细流程图: (1)PC端打开网页(显示出二维码),这时候会保存对应的randnumber(比如:12345678). (2)Android客户端扫码登录,Andro ...
随机推荐
- zend studio 13 curl 请求本机地址 无法跟踪调试的问题解决方案。。。(chrome等浏览器调试原理相同)
方案如下: <?php $ch = curl_init (); curl_setopt ($ch, CURLOPT_URL, 'http://YOUR-SITE.com/your-script. ...
- 高性能MySQL --- 读书笔记(1) - 2016/8/2
此书不但帮助MySQL初学者提高使用技巧,更为有经验的MySQL DBA指出了开发高性能MySQL应用的途径.全书包括14章,内容覆盖MySQL系统架构.设计应用技巧.SQL语句优化.服务器性能调优. ...
- jQuery实现网站图片放大效果
实现效果:当鼠标指向商品图片时,图片会自动放大. <!DOCTYPE html> <html> <head> <meta charset="UTF- ...
- 【宋红康学习日记1】关于环境变量设置出现的问题——找不到或无法加载主类 java
忙活了一整天,最后被自己的小愚蠢所拜倒,不过也是学习到了很多,知道了出现问题怎样去解决. 问题是在cmd运行环境中编译我的第一个小程序HelloWorld时,javac命令可以运行,但是java命令后 ...
- 【转】分析Redis架构设计
一.前言 因为近期项目中开始使用Redis,为了更好的理解Redis并应用在适合的业务场景,需要对Redis设计与实现深入的理解. 我分析流程是按照从main进入,逐步深入分析Redis的启动流程.同 ...
- C#调用MySql
1.要连接MySql数据库必须首先下载MySql官方的连接.net的文件,文件下载地址为http://dev.mysql.com/downloads/connector/net/6.6.html#do ...
- 黄聪:C#中WebClient自动判断编码是UTF-8还是GBK,并且有超时判断功能
public class WebDownload : WebClient { private int _timeout; /// <summary> /// 超时时间(毫秒) /// &l ...
- Redis应用案例,查找某个值的范围(转)
本文来自Redis在Google Group上的一个问题,有一位同学发贴求助,说要解决如下的一个问题:他有一个IP范围对应地址的列表,现在需要给出一个IP的情况下,迅速的查找到这个IP在哪个范围,也就 ...
- memcache 内部原理实现
Lazy Expiration memcached 内部不会监视记录是否过期,而是在 get 时查看记录的时间戳,检查记录是否过期.这 种技术被称为 lazy(惰性)expiration.因此,mem ...
- webView--总结
Anaroid WebView API详解--http://blog.csdn.net/zhangcanyan/article/details/51344090;Android5.1系统WebView ...