一、资源下载
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在操作过程中,出现内存泄漏问题 |