前面的文章《如何用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_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);
類似地,我們生成一維碼的接口函數也相近,如下所示:
/****************************************************************************
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_CODE
Notes : 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 < 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
#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_CODE
Notes : 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_CODE
Notes : 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_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)
{
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 < 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
#define QRCODE_MAX_LEN 500 //max string len for creating qrcode
#define BARCODE_MAX_LEN 100 //max string len for creating barcode
typedef 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_CODE
Notes : 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_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__ */
下面我們通過一個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
// Project Header
#include "zint_code.h"
int 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代碼生成一維碼就介紹到這里了。有興趣的童鞋可以私下聯系,互相學習。
?審核編輯:湯梓紅
-
二維碼
+關注
關注
7文章
424瀏覽量
26452 -
C語言
+關注
關注
180文章
7604瀏覽量
136692 -
C代碼
+關注
關注
1文章
89瀏覽量
14297
發布評論請先 登錄
相關推薦
評論