C语言生成二维码
使用到的库:libzint
环境:centos
需要安装的环境:
gcc / cmake / zlib-devel /libpng-devel (均使用yum安装即可)
1、下载zint
https://sourceforge.net/projects/zint/
2、安装zint
tar xvf zint-2.9.1-src.tar.gz cd zint-2.9.1-src mkdir build cd build/
编译安装 [root@cc build]# cmake .. -- The C compiler identification is GNU 8.3.1 -- The CXX compiler identification is GNU 8.3.1 -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done -- Performing Test CXX_COMPILER_FLAG_WALL -- Performing Test CXX_COMPILER_FLAG_WALL - Success -- Found ZLIB: /usr/lib64/libz.so (found version "1.2.11") -- Found PNG: /usr/lib64/libpng.so (found version "1.6.34") CMake Warning at CMakeLists.txt:84 (find_package): By not providing "FindQt5UiTools.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "Qt5UiTools", but CMake did not find one. Could not find a package configuration file provided by "Qt5UiTools" with any of the following names: Qt5UiToolsConfig.cmake qt5uitools-config.cmake Add the installation prefix of "Qt5UiTools" to CMAKE_PREFIX_PATH or set "Qt5UiTools_DIR" to a directory containing one of the above files. If "Qt5UiTools" provides a separate development package or SDK, be sure it has been installed. -- Configuring done -- Generating done -- Build files have been written to: /opt/zint-2.9.1-src/build
[root@cc build]# make -j4 Scanning dependencies of target zint [ 4%] Building C object backend/CMakeFiles/zint.dir/vector.c.o [ 4%] Building C object backend/CMakeFiles/zint.dir/ps.c.o [ 6%] Building C object backend/CMakeFiles/zint.dir/svg.c.o [ 8%] Building C object backend/CMakeFiles/zint.dir/emf.c.o [ 10%] Building C object backend/CMakeFiles/zint.dir/bmp.c.o [ 12%] Building C object backend/CMakeFiles/zint.dir/pcx.c.o [ 14%] Building C object backend/CMakeFiles/zint.dir/gif.c.o [ 16%] Building C object backend/CMakeFiles/zint.dir/png.c.o [ 18%] Building C object backend/CMakeFiles/zint.dir/tif.c.o [ 20%] Building C object backend/CMakeFiles/zint.dir/raster.c.o [ 22%] Building C object backend/CMakeFiles/zint.dir/output.c.o [ 24%] Building C object backend/CMakeFiles/zint.dir/common.c.o [ 26%] Building C object backend/CMakeFiles/zint.dir/library.c.o [ 28%] Building C object backend/CMakeFiles/zint.dir/large.c.o [ 30%] Building C object backend/CMakeFiles/zint.dir/reedsol.c.o [ 32%] Building C object backend/CMakeFiles/zint.dir/gs1.c.o [ 34%] Building C object backend/CMakeFiles/zint.dir/eci.c.o [ 36%] Building C object backend/CMakeFiles/zint.dir/general_field.c.o [ 38%] Building C object backend/CMakeFiles/zint.dir/sjis.c.o [ 40%] Building C object backend/CMakeFiles/zint.dir/gb2312.c.o [ 42%] Building C object backend/CMakeFiles/zint.dir/gb18030.c.o [ 44%] Building C object backend/CMakeFiles/zint.dir/code.c.o [ 46%] Building C object backend/CMakeFiles/zint.dir/code128.c.o [ 48%] Building C object backend/CMakeFiles/zint.dir/2of5.c.o [ 50%] Building C object backend/CMakeFiles/zint.dir/upcean.c.o [ 52%] Building C object backend/CMakeFiles/zint.dir/telepen.c.o [ 54%] Building C object backend/CMakeFiles/zint.dir/medical.c.o [ 56%] Building C object backend/CMakeFiles/zint.dir/plessey.c.o [ 58%] Building C object backend/CMakeFiles/zint.dir/rss.c.o [ 60%] Building C object backend/CMakeFiles/zint.dir/postal.c.o [ 62%] Building C object backend/CMakeFiles/zint.dir/auspost.c.o [ 64%] Building C object backend/CMakeFiles/zint.dir/imail.c.o [ 66%] Building C object backend/CMakeFiles/zint.dir/mailmark.c.o [ 68%] Building C object backend/CMakeFiles/zint.dir/code16k.c.o [ 70%] Building C object backend/CMakeFiles/zint.dir/codablock.c.o [ 72%] Building C object backend/CMakeFiles/zint.dir/dmatrix.c.o [ 74%] Building C object backend/CMakeFiles/zint.dir/pdf417.c.o [ 76%] Building C object backend/CMakeFiles/zint.dir/qr.c.o [ 78%] Building C object backend/CMakeFiles/zint.dir/maxicode.c.o [ 80%] Building C object backend/CMakeFiles/zint.dir/composite.c.o [ 82%] Building C object backend/CMakeFiles/zint.dir/aztec.c.o [ 84%] Building C object backend/CMakeFiles/zint.dir/code49.c.o [ 86%] Building C object backend/CMakeFiles/zint.dir/code1.c.o [ 88%] Building C object backend/CMakeFiles/zint.dir/gridmtx.c.o [ 90%] Building C object backend/CMakeFiles/zint.dir/hanxin.c.o [ 92%] Building C object backend/CMakeFiles/zint.dir/dotcode.c.o [ 94%] Building C object backend/CMakeFiles/zint.dir/ultra.c.o [ 96%] Linking C shared library libzint.so [ 96%] Built target zint Scanning dependencies of target zint_frontend [ 98%] Building C object frontend/CMakeFiles/zint_frontend.dir/main.c.o [100%] Linking C executable zint [100%] Built target zint_frontend
[root@cc build]# make install [ 96%] Built target zint [100%] Built target zint_frontend Install the project... -- Install configuration: "RelWithDebInfo" -- Up-to-date: /usr/local/share/apps/cmake/modules/FindZint.cmake -- Installing: /usr/local/lib/libzint.so.2.9.0 -- Up-to-date: /usr/local/lib/libzint.so.2.9 -- Up-to-date: /usr/local/lib/libzint.so -- Up-to-date: /usr/local/include/zint.h -- Installing: /usr/local/bin/zint
3、测试安装是否成功
4、Demo测试产生二维码
4-1 zint_code.h
#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 = 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; /**************************************************************************** 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__ */
4-2 zint_code.c
#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 = 0; if(!pQrCodeData) //check input pointer { return ZINT_ERR_INV_DATA; } if(QrcodeLen == 0) { QrcodeLen = strlen((char *)pQrCodeData); } if(QrcodeLen > QRCODE_MAX_LEN)//len is too long { return ZINT_ERR_TOO_LONG; } if(0 == 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 = 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, pQrCodeData, QrcodeLen, 0); ZBarcode_Clear(pMySymbol); ZBarcode_Delete(pMySymbol); //release memory in zint lib if(pZintRet) { *pZintRet = RetCode; //save ret code from zint lib } return ((0 == RetCode) ? (ZINT_OK) : (ZINT_ERR_LIB_RET)); }
4-3 qrcode_test.c
/**************************************************************************** * File : qrcode_test.c * * Copyright (c) Marshu * * DESCRIPTION: Demo for creating qrcode by C code. * * Modification history * -------------------------------------------------------------------------- * Date Version Author History * -------------------------------------------------------------------------- * 2021-02-25 1.0.0 Marshu written * * Need to install: * yum -y install zlib-devel; yum -y install libpng-devel; libzint library * * zint download link: * https://sourceforge.net/projects/zint/ ***************************************************************************/ #include <stdio.h> #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[] = "Test zint QRCode. 测试一下gbk编码 ..."; 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, 0, 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); } return 0; }
5、编译代码
gcc -o qrcode_test -lzint zint_code.c zint_code.h qrcode_test.c
6、运行代码
[root@cc home]# ./qrcode_test ./qrcode_test: error while loading shared libraries: libzint.so.2.9: cannot open shared object file: No such file or directory
出现上述运行错误,修改一下如下路径
export LD_LIBRARY_PATH=/usr/local/lib
[root@cc home]# ./qrcode_test [ qrcode_test.c, 40] Create qrcode OK ! View qrcode file : MyQrcode.png in cur path. ZintRet = 0, ZintLibRet = 0
END