SOUI基于Zint生成Code 2 of 5码

在 Zint 中,BARCODE_C25STANDARD、BARCODE_C25INTER、BARCODE_C25IATA、BARCODE_C25LOGIC 和 BARCODE_C25IND 是 Code 2 of 5(Code 25)条形码的不同变体。这些变体在编码规则、字符集和应用场景上有所不同。Code 2 of 5(Code 25)是一种基于宽条和窄条的条形码,每个字符由 5 个条组成,其中 2 个是宽条,3 个是窄条。

BARCODE_C25STANDARD码:

  • 标准 Code 2 of 5 条形码。
  • 仅支持数字 0-9。
  • 通用场景,适合简单的数字编码。
    在使用时可指定是否添加校验码,文档中描述为:
    No check digit is added by default. To add a check digit, set --vers=1 (API option_2 = 1). To add a check digit but not show it in the Human Readable Text, set --vers=2 (API option_2 = 2).
    默认情况下不添加校验位,如要设置校验位则将option_2设置为1即可;如果要添加校验位但不可见则将option_2设置为2即可。
    校验码计算规则:
  • 从右到左(从最后一位字符开始),为每个字符分配一个权重,权重交替为 3 和 1。
  • 将每个字符的值乘以其权重,然后求和。
  • 将加权和除以 10,取余数,然后用 10 减去余数。如果结果为 10,则校验码为 0。
    BARCODE_C25STANDARD、BARCODE_C25INTER、BARCODE_C25IATA、BARCODE_C25LOGIC 和 BARCODE_C25IND码的校验码计算方法都一样。

BARCODE_C25INTER码:

  • Interleaved 2 of 5(交错 2 of 5)条形码。
  • 仅支持数字 0-9。如果非偶数位则在前边补0
  • 每两个数字编码为一个字符。第一个数字用条表示,第二个数字用空表示。
  • 广泛应用于物流、零售和仓库管理。
    支持可选的校验位(通常使用 Modulo 10 校验)。
    默认情况下不添加校验位,如要设置校验位则将option_2设置为1即可;如果要添加校验位但不可见则将option_2设置为2即可。

BARCODE_C25IATA码:

  • IATA 2 of 5 条形码。
  • 仅支持数字 0-9。
  • 与标准 Code 2 of 5 类似,但专为国际航空运输协会(IATA)设计。
  • 一般用于航空运输和行李标签。
    支持可选的校验位。
    默认情况下不添加校验位,如要设置校验位则将option_2设置为1即可;如果要添加校验位但不可见则将option_2设置为2即可。

BARCODE_C25LOGIC码:

  • Logic 2 of 5 条形码。
  • 仅支持数字 0-9。
  • 每个字符由 3 个窄条和 2 个宽条组成。字符之间用窄空分隔。
  • 一般用于电子设备和工业自动化。
    支持可选的校验位。
    默认情况下不添加校验位,如要设置校验位则将option_2设置为1即可;如果要添加校验位但不可见则将option_2设置为2即可。

BARCODE_C25IND码:

  • Industrial 2 of 5 条形码。
  • 仅支持数字 0-9。
  • 每个字符由 3 个窄条和 2 个宽条组成。字符之间用窄空分隔。
  • 一般用于工业标识和仓库管理。
    支持可选的校验位。
    默认情况下不添加校验位,如要设置校验位则将option_2设置为1即可;如果要添加校验位但不可见则将option_2设置为2即可。

以下即为生成代码:

cpp 复制代码
struct zint_symbol* symbol;
symbol = ZBarcode_Create();
symbol->symbology = BARCODE_C25STANDARD;   //码制
symbol->input_mode = DATA_MODE; //数据编码格式
symbol->option_2 = 1;   //默认不校验、1 校验

std::string strContent = "123456";
CRect rcCode(0,0,200,50);
int nRet = ZBarcode_Encode_and_Buffer_Vector(symbol, (unsigned char*)strContent.c_str(), strContent.size(), 0);
if (nRet == 0)
{
    //success
    ZBarcode_Print(symbol, 0);
    std::vector<CRect> vecBlackRect;
    if (symbol->vector)
    {
        struct zint_vector_rect* rect = symbol->vector->rectangles;
        while (rect)
        {
            CRect rcTmp;
            rcTmp.left = rect->x;
            rcTmp.top = rect->y;
            rcTmp.right = rcTmp.left + rect->width;
            rcTmp.bottom = rcTmp.top + rect->height;
            vecBlackRect.push_back(rcTmp);
            rect = rect->next;        
        }    
    }
    double nDrawUint = (double)rcCode.Width() / symbol->width;
    double nUint = (double)symbol->bitmap_width / symbol->width;
    
    std::vector<CRect> vecDrawBlack;  //绘制条码条的真实区域
    for (int i = 0; i < vecBlackRect.size(); i++)
    {
        CRect rcTmp(vecBlackRect[i]);
        rcTmp.left = rcTmp.left / nUint * nDrawUint;
        rcTmp.right = rcTmp.right / nUint * nDrawUint;
        rcTmp.bottom = rcTmp.top + rcCode.Height();
        vecDrawBlack.push_back(rcTmp);   
    }
    
    //绘制条码
    //可选择是否绘制条码背景色
    {
        COLORREF clrBkgnd = GETCOLOR(L"RGB(255,255,255)");
        CAutoRefPtr<IBrush> brush, oldbrush;
        pRT->CreateSolidColorBrush(clrBkgnd, &brush);
        pRT->SelectObject(brush, (IRenderObj**)&oldbrush);
        pRT->FillRectangle(&rcCode);
        pRT->SelectObject(oldbrush, NULL);    
    }
    CAutoRefPtr<IPath> path;
    GETRENDERFACTORY->CreatePath(&path);
    for (int i = 0; i < vecDrawBlack.size(); i++)
    {
        CRect rcBlack;
        rcBlack.left += vecDrawBlack[i].left + rcCode.left;
        rcBlack.top += vecDrawBlack[i].top + rcCode.top;
        rcBlack.right = rcBlack.left + vecDrawBlack[i].Width();
        rcBlack.bottom = rcBlack.top + vecDrawBlack[i].Height();
        path->addRect(rcBlack);  
    }
    COLORREF clrFrgnd = GETCOLOR(L"RGB(0,0,0)"); //可自定义条码前景色
    CAutoRefPtr<IBrush> brush, oldbrush;
    pRT->CreateSolidColorBrush(clrFrgnd, &brush);
    pRT->SelectObject(brush, (IRenderObj**)&oldbrush);
    pRT->FillPath(path);
    pRT->SelectObject(oldbrush, NULL);
    
    //绘制文本(文本绘制可以选择绘制在底部还是顶部,自行计算文本位置然后进行绘制)
    SIZE szContent;
    pRT->MeasureText(m_sstrContent, m_sstrContent.GetLength(), &szContent); //文本整体的长度
    CRect rcText(rcCode);
    rcText.top = rcCode.bottom;
    rcText.bottom = rcText.top + szContent.cy;
    pRT->DrawText(m_sstrContent, -1, (LPRECT)rcText, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
}
else
{
    //failed
    //可查看errtxt值查看失败描述
}
ZBarcode_Delete(symbol);
相关推荐
陈浩源同学2 分钟前
学习 TypeScript 栈和队列数据结构
前端·算法
卷卷的小趴菜学编程24 分钟前
c++之多态
c语言·开发语言·c++·面试·visual studio code
夏末秋也凉44 分钟前
力扣-回溯-491 非递减子序列
数据结构·算法·leetcode
penguin_bark1 小时前
三、动规_子数组系列
算法·leetcode
OopspoO1 小时前
C++ 标准库——函数对象和函数适配器
c++
kyle~1 小时前
thread---基本使用和常见错误
开发语言·c++·算法
攻城狮7号1 小时前
【第三节】C++设计模式(创建型模式)-单例模式
c++·单例模式·设计模式
曲奇是块小饼干_1 小时前
leetcode刷题记录(一百零八)——322. 零钱兑换
java·算法·leetcode·职场和发展
小wanga2 小时前
【leetcode】滑动窗口
算法·leetcode·职场和发展
少年芒2 小时前
Leetcode 490 迷宫
android·算法·leetcode