一维码和二维码开源库zint学习

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hhhuang1991/article/details/83378108

一、资源下载

zint本来是可以不需要任何其他库(libpng和zlib)的支持,但是如果希望zint能够生成PNG格式的图片,那么就需要libpng的支持,而libpng需要zlib的支持。
zint下载:https://github.com/zint/zint
libpng库下载:https://sourceforge.net/projects/libpng/files/libpng16/
zlib下载:https://sourceforge.net/projects/zlib/

二、编译zint

环境:Win7 64位系统,VS2015编译平台

2.1、依赖库libpng和zlib的编译

libpng版本为最新版本1.6.35,zlib版本为最新版本1.2.11。libpng资源解压后,根目录中会出现一个projects的文件夹,在\projects\vstudio目录下,找到VS2010的工程文件vstudio.sln。

2.1.1 、静态库zlib编译

运行vstudio.sln工程,工程中包含7个子工程,其中zlib和libpng是我们需要编译的。由于libpng需要zlib库的支持,我们先要编译zlib库,zlib库的配置是一个静态库(可以在工程的属性中查看得知)。
在这里插入图片描述
首次编译,应该是会出现下面的错误:
在这里插入图片描述
分析上面的错误可知,工程的源代码文件在“…\zlib-1.2.8\”目录中找不到,找不到是正常的,我们确实没有这个文件夹以及相关的文件,libpng库中没有包含zlib所需要的源代码文件。
将下载的zlib库资源解压,在根目录下会找到上面所需要的所有源代码文件。删除zint工程中不存在的那些文件条目,然后添加我们下载的zlib库资源中的文件,如下图所示,
在这里插入图片描述
然后再编译,应该会成功产生一个静态库文件zlib.lib。

2.1.2、libpng库编译

在上面的VS工程中,选中libpng子工程,直接编译,会出现“找不到zlib.h文件”的错误。需要将zlib.h的目录包含到libpng工程中去,如下图所示,
在这里插入图片描述
然后再编译, 应该会成功产生一个libpng16.dll和libpng6.lib文件。

2.2、zint库编译

zint版本为2.6.1。
解压后,在根目录下找到win32文件夹,打开zint.sln工程,整个工程包含两个子项目:zint和libzint。zint为测试项目,libzint为库项目,我们重点关注libzint项目。
在工程中选中libzint,直接编译。初次编译,应该可以成功生成一个libzint.dll和libzint.lib文件,在不需要生成PNG图片的程序中,这个zint库文件就满足要求了。但是,如果要在程序中生成PNG格式的条码图片时,则需要在libzint项目中加入libpng库文件。步骤如下,

  • 去掉libzint项目中的预编译头NO_PNG。选中libzint属性【配置属性 - C/C++ - 预处理器】,预处理器定义中去掉NO_PNG条目即可;
  • 添加libpng和zlib库文件。根据libzint项目属性中的配置目录,在win32的同一级别目录中创建extern\libpng\include\、extern\libpng\lib\x86\、extern\zlib\include\,extern\zlib\lib\x86\四个文件夹,并将2.1中生成的相应的文件拷贝进去,
    extern\libpng\include\ : png.h,pngconf.h,pnglibconf.h,zconf.h
    extern\libpng\lib\x86\ : libpng16.lib
    extern\zlib\include\ : zlib.h
    extern\zlib\lib\x86\ : zlib.lib
  • 将libpng16.dll放到目标文件生成目录中。

然后再次编译,就会生成支持PNG的libzint.dll和libzint.lib文件。

三、简单示例

在程序中使用zint库文件,需要上面编译生成的几个文件:zint.h,libzint.lib,libpng16.dll,libzint.dll
如何在程序中使用DLL?

#include "stdafx.h"
#include <iostream>
#include "zint.h"

using namespace std;

#pragma comment(lib, "libzint.lib")

int main()
{
	// Create symbol
	zint_symbol * pSymbol = ZBarcode_Create();
	if (nullptr == pSymbol)
	{
		cout << "Symbol create fail !" << endl;
	}
	else
	{
		cout << "Symbol create success !" << endl;
	}

	cout << "zint version:" << ZBarcode_Version() << endl;
	// 改变条码前景色
	strcpy(pSymbol->fgcolour, "00FF00");
	// 改变条码背景色
    strcpy(pSymbol->bgcolour, "000000");
	// 改变图片路径
	strcpy(pSymbol->outfile, "images/out2.png");

	pSymbol->scale = 1;

	//strcpy(pSymbol->primary, "999999999840012");

	//pSymbol->output_options = BARCODE_BOX | BARCODE_BIND;

	//pSymbol->whitespace_width = 1;
	//pSymbol->border_width = 1;

	pSymbol->symbology = BARCODE_AZTEC;
	pSymbol->option_1 = 2;
	pSymbol->option_2 = 0;  // 条码的大小
	pSymbol->option_3 = 928;

	//pSymbol->option_3 = DM_SQUARE;  // 
	
	// Encoding and saving to file
	//char buff[1024];
	//memset(buff, 0, 1024);
	//cout << "请输入条码的内容:";
	//cin >> buff;
	// ZBarcode_Encode(pSymbol, (unsigned char *)buff, 0);
	// ZBarcode_Print(pSymbol, 0);
	// ZBarcode_Encode_and_Print(pSymbol, (unsigned char *)buff, 0, 90);
	int error = 0;
	error = ZBarcode_Encode_and_Print(pSymbol, (unsigned char *)"1234567", 0, 0);
	if (error != 0)
	{
		cout << "Error: " << pSymbol->errtxt << endl;
	}
	if (error > ZINT_WARN_INVALID_OPTION)
	{
		ZBarcode_Delete(pSymbol);
		getchar();
		return 1;
	}
	// ZBarcode_Delete(pSymbol);
	// ZBarcode_Encode_and_Buffer(pSymbol, (unsigned char *)buff, 0, 0);

	//int i = 0;
	//for (int row = 0; row < pSymbol->bitmap_height; row++)
	//{
	//	for (int col = 0; col < pSymbol->bitmap_width; col++)
	//	{
	//		int red = pSymbol->bitmap[i];
	//		int green = pSymbol->bitmap[i + 1];
	//		int blue = pSymbol->bitmap[i + 2];
	//		cout << "(" << red << "," << green << "," << blue << ")" << ",";
	//		i += 3;
	//	}
	//	cout << endl;
	//}

	ZBarcode_Delete(pSymbol);
	getchar();
    return 0;
}

四、QT界面的zint操作工具

zint库中,还提供了基于QT的界面操作工具源码。分为两个工程,一个是静态库工程backend_qt,一个是exe工程frontend_qt。下面详细讲述如何编译。

4.1、编译backend_qt

在根目录中,找到backend_qt文件夹,在QtCreator中打开backend_qt.pro工程,直接编译,会发现找不到“png.h”文件,这个与上面的编译错误是一致的,就是工程目录配置不正确。正确配置一下即可,如下图所示,
在这里插入图片描述
在这里插入图片描述
再次编译,应该能够成功产生一个静态库QtZint.lib文件。

4.2、编译frontend_qt

在根目录中,找到frontend_qt文件夹,在QtCreator中打开frontend_qt.pro工程,直接编译,会出现找不到QtZint.lib库,libpng16.lib库、zlib.lib库。同样,这也是由于工程目录配置不正确的原因,如下图所示,
在这里插入图片描述
在这里插入图片描述
因为libpng是DLL库,所以还需要将对应的libpng.dll放在frontend_qt目标文件目录中。
最后编译可以通过,当时运行会出现CrtIsValidHeapPointer错误,猜测是由于DLL版本不匹配引起的,但是最终还是没有找到原因。这里提供一个编译成功的exe文件和zint开发手册链接地址:https://pan.baidu.com/s/1ncJIod01xB0yVS6hZhK-oQ,提取码:yev9

五、开发应用

1、zint_symbol解析

zint_symbol结构体的定义位于zint.h文件中,详细说明见如下表格

变量名称 类型 含义 默认值
symbology integer 条码类型(详细见zint.h声明) BARCODE_CODE128
height integer 条码的高度 ,详细参考注意第一点 50
whitespace_width integer 左右空白的宽度 0
border_width integer 边框的宽度 0
output_options integer 条码是否添加边框或边界线 (none)
fgcolour character string 条码前景颜色,格式为RGB16进制的字符串,例如,绿色“00FF00” “000000”
bgcolour character string 条码背景颜色,格式与fgcolour一致 “FFFFFF”
outfile character string 条码图片输出的文件路径,包含文件名和后缀(所指定的路径必须已经存在) “out.png”
option_1 integer 一般为校验等级,具体见zint开发文档 (automatic)
option_2 integer 一般为版本大小,具体见zint开发文档 (automatic)
option_2 integer 具体见zint开发文档 (automatic)
scale float 条形码尺寸的缩放因子 1.0
input_mode integer BINARY_MODE
primary character string 对于许多复杂的条形码,显示主要的信息 NULL
text unsigned character string NULL
rows integer BARCODE_CODE128
width integer 条码的宽度 只读
encoding_data array of character string 条码编码数据的描述 只读
row_height array of integers 条码一行的高度
errtxt character string 错误信息 只读
bitmap pointer to character array 指向图片中的条码位图信息 只读
bitmap_width integer 条码位图的像素宽度 只读
bitmap_height integer 条码位图的像素高度 只读

注意:1、当条码类型为下面这些条码时,忽略高度:
Australia Post 4-State Barcodes, PostNet, PLANET, USPS OneCode,RM4SCC, PDF417, Data Matrix, Maxicode, QR Code, GS1 DataBar-14 Stacked, PDF417,MicroPDF417
2、当条码类型为Code 16k 和 ITF-14 symbols时,忽略输出选项
3、whitespace_width,空白的宽度,只会增加条码左右两侧的空白
4、border_width,边框宽度。如果output_options没有设置边框,设置了border_width,条码周围也会出现空白边框

2、错误信息

返回值 含义
WARN_INVALID_OPTION zint_symbol结构体中某个变量设置错误,但是程序通过猜测变量应该是什么内容,而去生成一个条形码
ERROR_TOO_LONG 输入的数据过长或者过短,不会产生条码
ERROR_INVALID_DATA 输入的数据中包含被条码禁止的字符(比如,在EAN条形码中输入字母),不会产生条码
ERROR_INVALID_CHECK ISBN类型条码中被输入一个错误的校验码,不会产生条码
ERROR_INVALID_OPTION zint_symbol结构体中某个变量设置错误,程序不能猜测变量应该是什么内容,不会产生条码
ERROR_ENCODING_PROBLEM 编码错误,一般不会产生这个错误
ERROR_FILE_ACCESS 当采用读取文件的方式去获取字符时,如果zint没有权限去操作指定的文件,就会出错
ERROR_MEMORY zint在操作过程中,出现内存泄漏问题

猜你喜欢

转载自blog.csdn.net/hhhuang1991/article/details/83378108