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

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

3天内不再提示

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

嵌入式物联网开发 来源:嵌入式物联网开发 作者:嵌入式物联网开发 2022-08-25 12:42 次阅读

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

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

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

​编辑

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

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

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

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

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

​审核编辑:汤梓红

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

    关注

    7

    文章

    371

    浏览量

    26082
  • C语言
    +关注

    关注

    180

    文章

    7530

    浏览量

    128729
  • C代码
    +关注

    关注

    1

    文章

    89

    浏览量

    14177
收藏 人收藏

    评论

    相关推荐

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

    【C语言应用】如何用C代码生成二维码?
    的头像 发表于 08-24 19:01 1703次阅读
    【C<b class='flag-5'>语言</b>应用】如<b class='flag-5'>何用</b>C<b class='flag-5'>代码</b><b class='flag-5'>生成</b>二维码?

    何用C语言对汇编语言进行调用

    何用C语言对汇编语言进行调用
    发表于 08-20 22:59

    懒人C51代码生成

    懒人C51代码生成器,款小软件
    发表于 11-30 00:18

    何用C语言生成高斯粗糙面

    关于生成高斯粗糙面很多都是用MATLAB生成的,不知道怎么用C语言去做,有没有粗糙面模拟或雷达截面计算方面的讲如何模拟,计算的书。。。现在手头有雷达截面与隐身技术及雷达目标特性两本书,
    发表于 03-11 21:07

    阿里云SDK再升级,宣布支持C++语言

    摘要: 日前,阿里云官方SDK发布支持新语言——C++ 语言SDK,意味着90%以上产品可以随时生成并发布C++ SDK,给
    发表于 02-08 13:48

    求助激光三测量的单片机C语言代码

    大佬们,我需要的份激光三测量的单片机C语言代码{:4:},不用太复杂,就是能测量物体的三
    发表于 04-24 09:15

    请问谁有二维码生成和解析源代码

    如题,最近对二维码感兴趣,谁有二维码生成和解析源代码,最好是C语言的,传
    发表于 03-11 05:55

    何用STM32CubeMX生成底层代码代码C++的编写要注意哪些事项?

    何用STM32CubeMX生成底层代码?单片机代码如何进行IDE的C++配置?代码
    发表于 07-01 06:22

    关于C语言的基础知识

    C语言基础知识关于C语言C语言相对于汇编是属于高
    发表于 08-20 07:03

    HarmonyOS教程—基于AI的生成能力,实现二维码生成与扫功能

    ,完成设备调试的相关配置:使用真机进行调试使用模拟器进行调试3. 代码结构解读工程结构描述如下:qrlibrarycoreGenerateCore:二维码生成核心类。ScannerCore:二
    发表于 08-30 14:01

    何用c语言去实现秒表的计数功能呢

    何用c语言去实现秒表的计数功能呢?其实现代码是怎样的?
    发表于 10-18 07:29

    何用C语言个查单词的小demo?

    何用C语言个查单词的小demo?
    发表于 10-27 06:34

    51单片机生成维码的步骤

    最近搞了个单片机生成维码,步骤如下1.下载QRCode生成的驱动源代码,这个驱动是c语言编写的
    发表于 11-19 07:33

    何用C语言代码去控制LED灯的亮灭呢

    何用汇编语言C语言环境进行初始化呢?如何用C语言代码
    发表于 11-29 06:05