条码生成 SDK - Zint 教程及示例

Zint 教程及示例


Introduction

Zint 是一款优秀的开源的条码生成工具,它跨平台,它支持超过50种条码,囊括目前市场上主流的条码类型,包括 QR、PDF417 等等。Zint 的源码你可以在其 官网首页 找到下载链接。除了源码,你还可以下载到带 Qt 界面的和命令行运行的 zint。我把这些都打包在 这里 了,快来下载啊。

Zint 的编译请参看我上一篇文章 在 Win vs2017 下编译 zint。再重申一遍,Zint本身并不依赖 libpng 和 zlib,除非你想将生成的条码保存为 PNG 格式的图片,否则不需要对 libpng 和 zlib 进行编译,只需要打开 zint 的工程文件,右键生成即可对 zint 进行编译(非常简单,这也说明 zint 对额外的库依赖非常少,这非常棒)。Zint 除了 PNG 格式外,还支持 BMP、SVG、ESP 图片格式。最近做的内容就完全没有用到 libpng 和 zlib,只是利用 zint 生成条码,然后将生成的位图转成 Opencv 的 Mat,对其做一些处理。保存什么的,完全交给 Opencv 了,因此也就不要 ligpng 和 zlib。

开始介绍 Zint 之前,我们先了解下 Zint 中使用到的一些术语,详细内容请看 Terms of Reference,本人对条码技术并不了解,这些术语好几个看不懂,下面只说个人认为比较重要的几个词:
1. Symbol,可以看成是编码之后生成的一张图
2. Symbology,代表一种编码方法。每种条码都有自己的编码标准。
3. Linear,应该是长条状的码,例如条形码。
4. Stacked,包含多个长条状码的码,例如 PDF417
5. Matrix,二维码,包括 QR、Maxicode 等等
6. x-dimension,最小模块的大小,通常是最小模块的宽,因为条码的模块大小有固定的长宽比,通过宽就能计算出长。对于条形码来说,x-dimension 表示一列的宽(像素大小);对于二维码来说,x-dimension 表示一个模块的宽(像素大小)

Show Me the Code

下面介绍 Zint 中常用的 API,以及各种设置

创建和删除Symbol

Symbol 作为 Zint 中最为重要的结构体,它包含所有的设置以及编码后的比特流。注意创建后一定记得要释放。创建和删除方法如下:

int CreateAndDeleteSymbol()
{
    struct zint_symbol *my_symbol; my_symbol = ZBarcode_Create();
    if (my_symbol != nullptr)
    {
        printf("Symbol successfully created!\n");
    }
    ZBarcode_Delete(my_symbol);
    return 0;
}

编码并保存为图片

Zint 支持将编码后的数据保存为图片,利用的 API 主要是下面这些:

// 将 input 前 length 个字符进行编码
 int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *input, int length);

// 对 filename 中的数据进行编码
int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename);

// 将 symbol 中编码后的数据旋转 rotate_angle 度,然后保存为图片
int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle);

// 编码、保存一步到位
int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle);

// 读取文件、编码、保存一步到位
int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, char *filename, int rotate_angle); 

其中, 如果 length=0,那么将编码整个字符串;rotate_angle 有效的角度为 0,90,180,270

因此,编码和保存有多种方法可以选择,具体代码如下:

int EncodingAndSavingToFile()
{
    struct zint_symbol *my_symbol;
    my_symbol = ZBarcode_Create();

    // Set output file name
    strcpy_s(my_symbol->outfile, "output.bmp");

    // Set encode data
    string encode_data("hello world");
    ZBarcode_Encode(my_symbol, (unsigned char*)encode_data.c_str(), 0);

    int error_num = ZBarcode_Print(my_symbol, 0);

    if (error_num != 0)
    {
        /* some error occurred */
        printf("%s\n", my_symbol->errtxt);
    }

    ZBarcode_Delete(my_symbol);
    return 0;
}

output.bmp-5.3kB

ZBarcode_Encode_File

int Test_ZBarcode_Encode_File()
{
    struct zint_symbol *my_symbol; 
    my_symbol = ZBarcode_Create();

    my_symbol->symbology = BARCODE_QRCODE;

    strcpy_s(my_symbol->outfile, "Test_ZBarcode_Encode_File.bmp");

    char filename[256] = "hello.txt";
    int error_num  = ZBarcode_Encode_File(my_symbol, filename);

    if (error_num != 0)
    {
        /* some error occurred */
        printf("%s\n", my_symbol->errtxt);
    }

    error_num = ZBarcode_Print(my_symbol, 90);

    if (error_num != 0)
    {
        /* some error occurred */
        printf("%s\n", my_symbol->errtxt);
    }

    ZBarcode_Delete(my_symbol);

    return error_num;
}

Test_ZBarcode_Encode_File.bmp-10kB

获取位图

除了将编码后的数据保存为图片外,Zint 还允许我们对这些数据进行像素级别的访问。利用下面几个 API 可以生成位图:

int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle);
int ZBarcide_Encode_and_Buffer(struct zint_symbol *symbol, unsigned char *input,
int length, int rotate_angle);
int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, char *filename,
int rotate_angle);

注意 ZBarcode_Print 和 ZBarcode_Buffer 只能用其中一个,否则 ZBarcode_Delete 会出现异常。搞不懂这算是 Bug 还是规定。

int BufferingSymbolsInMemory()
{
    struct zint_symbol *my_symbol;
    my_symbol = ZBarcode_Create();

    my_symbol->symbology = BARCODE_QRCODE;

    strcpy_s(my_symbol->outfile, "BufferingSymbolsInMemory.bmp");

    string encode_data("BufferingSymbolsInMemory");

    int error_num = ZBarcode_Encode_and_Buffer(my_symbol, (unsigned char*)encode_data.c_str(), 0, 0);

    int r, g, b;
    int i = 0;
    for (int row = 0; row < my_symbol->bitmap_height; ++row)
    {
        for (int col = 0; col < my_symbol->bitmap_width; ++col)
        {
            r = my_symbol->bitmap[i];
            g = my_symbol->bitmap[i + 1];
            b = my_symbol->bitmap[i + 2];

            i += 3;

            if (r == 0 && g == 0 & b == 0)
            {
                printf("■");
            }
            else
            {
                printf("□");
            }
        }

        printf("\n");
    }
    ZBarcode_Delete(my_symbol);
    return 0;
}

QQ截图20180814112929.png-18.2kB
将位图转换为 Opencv 的 Mat 也非常简单,一句话搞定:

cv::Mat mat(my_symbol->bitmap_height, my_symbol->bitmap_width, 
            CV_8UC3, my_symbol->bitmap)

设置前景色后景色

int Test_fg_bg_color()
{
    struct zint_symbol *my_symbol;
    my_symbol = ZBarcode_Create();

    my_symbol->symbology = BARCODE_QRCODE;
    strcpy_s(my_symbol->fgcolour, "00ff00");
    strcpy_s(my_symbol->bgcolour, "f0f00f");

    strcpy_s(my_symbol->outfile, "Test_fg_bg_color.bmp");

    string encode_data("Test_fg_bg_color");
    int error_num = ZBarcode_Encode(my_symbol, (unsigned char*)encode_data.c_str(), 0);

    error_num = ZBarcode_Print(my_symbol, 0);

    ZBarcode_Delete(my_symbol);
    return 0;
}

Test_fg_bg_color.bmp-5.3kB

设置边缘留白

边缘留白有两种:border_width 和 whitespace_width。区别在于 border_width 为上下左右统统留白,whitespace_width只留两边。此外,其单位是 x-dimension。

int Test_whitespace_width()
{
    struct zint_symbol *my_symbol;
    my_symbol = ZBarcode_Create();

    my_symbol->symbology = BARCODE_QRCODE;
    my_symbol->border_width = 20; // 20 个 x-dimension 大小

    strcpy_s(my_symbol->outfile, "Test_whitespace_width.bmp");

    // Set encode data
    string encode_data("Test_whitespace_width");
    ZBarcode_Encode(my_symbol, (unsigned char*)encode_data.c_str(), 0);

    int error_num = ZBarcode_Print(my_symbol, 0);

    if (error_num != 0)
    {
        /* some error occurred */
        printf("%s\n", my_symbol->errtxt);
    }

    ZBarcode_Delete(my_symbol);
    return 0;
}

Test_whitespace_width.bmp-49.8kB

放大(设置模块大小)

Zint 生成图片的大小不能直接指定,而是通过对最小模块的尺寸调整,等到不同大小的图片。设置 scale 可以对模块大小进行放大或者缩小。

int Test_scale()
{
    struct zint_symbol *my_symbol;
    my_symbol = ZBarcode_Create();

    my_symbol->symbology = BARCODE_QRCODE;
    my_symbol->scale = 5;

    strcpy_s(my_symbol->outfile, "Test_scale.bmp");

    string encode_data("Test_scale");
    int error_num = ZBarcode_Encode(my_symbol, (unsigned char*)encode_data.c_str(), 0);

    error_num = ZBarcode_Print(my_symbol, 0);

    ZBarcode_Delete(my_symbol);
    return 0;
}

Test_scale.bmp-129.7kB

其他

以上为常用功能,更多设置请参考官网设置,或者下载 Zint开发手册,进行查看。
开发手册详细的说明针对不同码,进行不同的设置,例如对于 QR 码,可以进行设置纠错等级,设置版本等等。

  • 1
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值