如何用C代码生成一维码

如何用C代码生成一维码

如何用C代码生成一维码

  前面的文章《如何用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

如何用C代码生成一维码如何用C代码生成一维码
  1 /****************************************************************************
  2  * File       : zint_code.c
  3  * 
  4  * Copyright (c) 2011 by Li.Recan < [email protected] >
  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 Code file API with C Code by calling zint lib.
 28            It's a common api for create barcode or qrcode.
 29 Input    : ZintCodeObj, the zint create code file object           
 30 Output   : ZintCodeObj, the zint create code file object 
 31 Return   : 0 is ok, and other values are fail. See the meanings in enum ZINT_RET_CODE
 32 Notes    : null
 33 ****************************************************************************/
 34 ZINT_RET_CODE Zint_Create_Code_File(STR_ZINT_CODE *ZintCodeObj)
 35 {
 36     struct zint_symbol *pMySymbol     = NULL;
 37     int RetCode                     = 0;    
 38     int CodeTypeIn                  = 0;
 39     
 40     if(!ZintCodeObj) //check input pointer
 41     {
 42         return ZINT_ERR_INV_DATA;
 43     }
 44 
 45     //check code type
 46     if(ZINT_BARCODE == ZintCodeObj->CodeType)
 47     {
 48         CodeTypeIn = BARCODE_CODE128;
 49     }
 50     else if(ZINT_QRCODE == ZintCodeObj->CodeType)
 51     {
 52         CodeTypeIn = BARCODE_QRCODE;
 53     }
 54     
 55     if(ZintCodeObj->CodeLen == 0)
 56     {
 57         ZintCodeObj->CodeLen = strlen((char *)ZintCodeObj->pCodeData);
 58     }
 59     if(ZintCodeObj->CodeLen > ZintCodeObj->MaxCodeLen)//len is too long
 60     {        
 61         return ZINT_ERR_TOO_LONG;
 62     }
 63 
 64     if(0 == ZBarcode_ValidID(CodeTypeIn))
 65     {
 66         return ZINT_ERR_INV_CODE_ID;
 67     }
 68     
 69     pMySymbol = ZBarcode_Create();
 70     if(pMySymbol == NULL)
 71     {
 72         return ZINT_ERR_MEMORY;
 73     }
 74 
 75     if(ZintCodeObj->pCodeFile)//when it's NULL, outfile will be "out.png"
 76     {
 77         if(strstr(ZintCodeObj->pCodeFile, "png") || (strstr(ZintCodeObj->pCodeFile, "eps")) || (strstr(ZintCodeObj->pCodeFile, "svg")))
 78         {
 79             strcpy(pMySymbol->outfile, ZintCodeObj->pCodeFile);
 80         }
 81         else
 82         {
 83             ZBarcode_Clear(pMySymbol);
 84             ZBarcode_Delete(pMySymbol); //release memory in zint lib
 85             return ZINT_ERR_FILE_NAME;
 86         }
 87     }
 88     pMySymbol->symbology     = CodeTypeIn;  
 89     if(BARCODE_QRCODE == CodeTypeIn) // special for qrcode
 90     {
 91         pMySymbol->option_1     = 3; //ECC Level.It can be large when ECC Level is larger.(value:1-4)  
 92         pMySymbol->scale         = 4; //contorl qrcode file size, default is 1, used to be 4   
 93     }
 94     pMySymbol->border_width     = 2; //set white space width around your qrcode and 0 is for nothing 
 95     
 96     RetCode = ZBarcode_Encode_and_Print(pMySymbol, ZintCodeObj->pCodeData, ZintCodeObj->CodeLen, 0);    
 97     ZBarcode_Clear(pMySymbol);
 98     ZBarcode_Delete(pMySymbol); //release memory in zint lib
 99 
100     if(ZintCodeObj->pZintRet)
101     {
102         *(ZintCodeObj->pZintRet) = RetCode; //save ret code from zint lib
103     }
104     
105     return ((0 == RetCode) ? (ZINT_OK) : (ZINT_ERR_LIB_RET));
106 }
107 
108 /****************************************************************************
109 Descpribe: Create Barcode API with C Code by calling zint lib.
110 Input    : pBarCodeData, the barcode data buf
111            BarcodeLen, the len of barcode data, but it can be 0
112            pBarCodeFile, the output file name of barcode, it can be NULL           
113 Output   : pZintRet, to store the ret code from linzint. 
114 Return   : 0 is ok, and other values are fail. See the meanings in enum ZINT_RET_CODE
115 Notes    : pBarCodeFile, Must end in .png, .eps or .svg. when isn,t NULL string.
116 ****************************************************************************/
117 ZINT_RET_CODE Zint_Create_BarCode(uint8_t *pBarCodeData, int BarcodeLen, char *pBarCodeFile, int *pZintRet)
118 {
119     STR_ZINT_CODE ZintCodeObj;
120     
121     memset(&ZintCodeObj, 0, sizeof(STR_ZINT_CODE));
122     ZintCodeObj.pCodeData   = pBarCodeData;
123     ZintCodeObj.CodeLen     = BarcodeLen;
124     ZintCodeObj.pCodeFile   = pBarCodeFile;
125     ZintCodeObj.pZintRet    = pZintRet;
126     
127     ZintCodeObj.CodeType    = ZINT_BARCODE;
128     ZintCodeObj.MaxCodeLen  = BARCODE_MAX_LEN;
129     
130     return Zint_Create_Code_File(&ZintCodeObj);
131 }
132 
133 /****************************************************************************
134 Descpribe: Create Qrcode API with C Code by calling zint lib.
135 Input    : pQrCodeData, the qrcode data buf
136            QrcodeLen, the len of qrcode data, but it can be 0
137            pQrCodeFile, the output file name of qrcode, it can be NULL           
138 Output   : pZintRet, to store the ret code from linzint. 
139 Return   : 0 is ok, and other values are fail. See the meanings in enum ZINT_RET_CODE
140 Notes    : pQrCodeFile, Must end in .png, .eps or .svg. when isn,t NULL string.
141 ****************************************************************************/
142 ZINT_RET_CODE Zint_Create_QrCode(uint8_t *pQrCodeData, int QrcodeLen, char *pQrCodeFile, int *pZintRet)
143 {
144     STR_ZINT_CODE ZintCodeObj;
145     
146     memset(&ZintCodeObj, 0, sizeof(STR_ZINT_CODE));
147     ZintCodeObj.pCodeData   = pQrCodeData;
148     ZintCodeObj.CodeLen     = QrcodeLen;
149     ZintCodeObj.pCodeFile   = pQrCodeFile;
150     ZintCodeObj.pZintRet    = pZintRet;
151     
152     ZintCodeObj.CodeType    = ZINT_QRCODE;
153     ZintCodeObj.MaxCodeLen  = QRCODE_MAX_LEN;
154     
155     return Zint_Create_Code_File(&ZintCodeObj);
156 }
zint_code.c
如何用C代码生成一维码如何用C代码生成一维码
 1 /****************************************************************************
 2  * File       : zint_code.h
 3  * 
 4  * Copyright (c) 2011 by Li.Recan < [email protected] >
 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 #define BARCODE_MAX_LEN        100 //max string len for creating barcode
27 
28 typedef enum 
29 {
30     ZINT_OK                 = 0,
31     ZINT_ERR_INV_DATA         = -1, //input invalid data
32     ZINT_ERR_TOO_LONG         = -2, //len for input data is too long    
33     ZINT_ERR_INV_CODE_ID     = -3,//the code type is not supported by zint
34     ZINT_ERR_MEMORY         = -4, //malloc memory error in zint lib
35     ZINT_ERR_FILE_NAME        = -5, //qrcode file isn'y end in .png, .eps or .svg.
36     ZINT_ERR_LIB_RET         = -6, //zint lib ret error, real ret code should be zint api ret code
37 }ZINT_RET_CODE;
38 
39 typedef enum
40 {
41     ZINT_BARCODE            = 1, //barcode type
42     ZINT_QRCODE             = 2, //qrcode type
43 }CODE_TYPE;
44 
45 typedef struct
46 {
47     uint8_t *pCodeData;
48     int CodeLen;
49     char *pCodeFile;
50     CODE_TYPE CodeType;
51     int MaxCodeLen;
52     int *pZintRet;
53 }STR_ZINT_CODE;  //struct for create code file
54 
55 /****************************************************************************
56 Descpribe: Create Barcode API with C Code by calling zint lib.
57 Input    : pBarCodeData, the barcode data buf
58            BarcodeLen, the len of barcode data, but it can be 0
59            pBarCodeFile, the output file name of barcode, it can be NULL           
60 Output   : pZintRet, to store the ret code from linzint. 
61 Return   : 0 is ok, and other values are fail. See the meanings in enum ZINT_RET_CODE
62 Notes    : pBarCodeFile, Must end in .png, .eps or .svg. when isn,t NULL string.
63 ****************************************************************************/
64 ZINT_RET_CODE Zint_Create_BarCode(uint8_t *pBarCodeData, int BarcodeLen, char *pBarCodeFile, int *pZintRet);
65 
66 /****************************************************************************
67 Descpribe: Create Qrcode API with C Code by calling zint lib.
68 Input    : pQrCodeData, the qrcode data buf
69            QrcodeLen, the len of qrcode data, but it can be 0
70            pQrCodeFile, the output file name of qrcode, it can be NULL           
71 Output   : pZintRet, to store the ret code from linzint. 
72 Return   : 0 is ok, and other values are fail. See the meanings in enum ZINT_RET_CODE
73 Notes    : pQrCodeFile, Must end in .png, .eps or .svg. when isn,t NULL string.
74 ****************************************************************************/
75 ZINT_RET_CODE Zint_Create_QrCode(uint8_t *pQrCodeData, int QrcodeLen, char *pQrCodeFile, int *pZintRet);
76 
77 #define Debuging(fmt, arg...)       printf("[%20s, %4d] "fmt, __FILE__, __LINE__, ##arg)
78 
79 #ifdef __cplusplus
80 }
81 #endif
82 
83 #endif /* __ZINT_CODE__ */
zint_code.h

  下面我们通过一个demo程序来验证下接口函数,即qrcode_test.c源程序,以下为其全部内容。

如何用C代码生成一维码如何用C代码生成一维码
 1 /****************************************************************************
 2  * File       : qrcode_test.c
 3  * 
 4  * Copyright (c) 2011 by Li.Recan < [email protected] >
 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     char BarcodeData[]      = "13430931801"; //barcode string
30     char BarcodeFile[]      = "MyBarcode.png";
31     
32     //test with inputing qrcode_file name
33     ZintRet = Zint_Create_QrCode((uint8_t*)QrcodeData, 0, QrcodeFile, &ZintLibRet);
34     if(ZINT_OK != ZintRet)
35     {
36         Debuging("Create qrcode err, ZintRet = %d, ZintLibRet = %d\n", ZintRet, ZintLibRet);
37     }
38     else
39     {
40         Debuging("Create qrcode OK ! \nView qrcode file : %s in cur path. ZintRet = %d, ZintLibRet = %d\n", QrcodeFile, ZintRet, ZintLibRet);
41     }
42     
43     //test without inputing qrcode_file name
44     ZintRet = Zint_Create_QrCode((uint8_t*)QrcodeDataDef, 0, NULL, &ZintLibRet);
45     if(ZINT_OK != ZintRet)
46     {
47         Debuging("Create qrcode err, ZintRet = %d, ZintLibRet = %d\n", ZintRet, ZintLibRet);
48     }
49     else
50     {
51         Debuging("Create qrcode OK ! \nView qrcode file : out.png in cur path. ZintRet = %d, ZintLibRet = %d\n", ZintRet, ZintLibRet);
52     }
53     
54     //test create barcode with name "MyBarcode.png"
55     ZintRet = Zint_Create_BarCode((uint8_t*)BarcodeData, 0, BarcodeFile, &ZintLibRet);
56     if(ZINT_OK != ZintRet)
57     {
58         Debuging("Create barcode err, ZintRet = %d, ZintLibRet = %d\n", ZintRet, ZintLibRet);
59     }
60     else
61     {
62         Debuging("Create barcode OK ! \nView barcode file : %s in cur path. ZintRet = %d, ZintLibRet = %d\n", BarcodeFile, ZintRet, ZintLibRet);
63     }    
64         
65     return 0;
66 }
qrcode_test.c

  前半部分还是保留上一次测试生产二维码的代码;而新增了生成一维码的测试代码。

 如何用C代码生成一维码

如何用C代码生成一维码 

  之后再运行demo程序,如下:

如何用C代码生成一维码 

  如框框所示,即为成功运行程序,生成的一维码图片。它的展示如下:

如何用C代码生成一维码

  用微信等扫一扫工具,扫描结果如下:

如何用C代码生成一维码

 

  结果正如我们代码所写,证明程序执行是没有问题的。

  好了,本期如何用C代码生成一维码就介绍到这里了。有兴趣的童鞋可以私下联系,互相学习。

 

 

posted @ 2016-10-31 10:29 Mr.Recan 阅读(...) 评论(...) 编辑 收藏