使用开源qrencode库生成二维码

 2022-5-5     作者:杨阳     [nemail]    
[lablebox]

二维码简介


  二维码是一个目前应用范围极广的一种编码方式。通过特定的几何图形,用黑白相间的点组成,利用计算机二进制0,1的概念,将字符串信息编码进图形中。从而可以通过光电扫描设备,如手机等来进行快速识别。


  相比于一维条码,二维码存储信息量更大,可靠性高,更易识别,可以在扭曲,部分遮挡的情况下被识别。


qrencode库简介


  二位码最常见的编码为QR code,qrencode是一个满足QR code标准的开源库。可以适用于各个平台。


Wince下使用方式


  1、可以在GITHUB找到qrencode库最新下载。

  2、新建一个wince平台的工程,选择新建c++下smart device的win32工程,选在一个WINCE平台,工程类型选择Static library。

  3、将下载的qrencode库里的.h文件及.c文件都添加入工程中,选择编译。

  4、编译可能会提示一些环境变量不存在的错误,比如errno = EINVAL;中的EINVAL未定义,将这类代码注释掉,这是因为wince将这部分功能精简掉了。

  5、最终编译成功会生成qrencodece.lib,将它和qrencodece.h添加入自己工程便可以使用了。

  6、定义一个Qrcode指针,调用方法QRcode_encodeString,传入参数1,要编码的字符串,参数2,编码的纠错等级,参数3,编码模式,通常使用QR_MODE_8,参数4,1或0,表示是否区分大小写。这样就可以获得一个编码后的2进制数组的数据指针。


QRcode* pQRC;
pQRC = QRcode_encodeString(“emtronix”, 0, QR_ECLEVEL_H, QR_MODE_8, 1))


  7、将该二维码据显示到屏幕中。


int width = pQRC->width;
 
CBrush brush;
brush.CreateStockObject(LTGRAY_BRUSH);
m_dcMem.FillRect(m_rect,&brush);
brush.DeleteObject();

int x, y, l, n;
unsigned char* pData;
pData = pQRC->data;
 
for (y= 0;y<width;y++)
{
    for (x= 0;x<width;x++)
    {
       if (*pData & 1)
       {
           for (l = 0; l < 8; l++)
           {
              for (n = 0; n < 8; n++)
              {
                  m_dcMem.SetPixel(x*8+l, y*8+n,RGB(0,0,0));
              }
           }
       }
       pData++;
    }
}
 
CDC *pDC=GetDC();
pDC->BitBlt(16, 40, 512, 512, &m_dcMem, 0, 0, SRCCOPY);
ReleaseDC(pDC);
QRcode_free(pQRC);


使用开源qrencode库生成二维码.png


  8、将该二维码数据保存到bmp格式图片文件中。


Width = pQRC->width;
Widthbmp = Width * 8 * 3;
if (Widthbmp % 4) Widthbmp = (Widthbmp / 4 + 1) * 4;
unDataBytes = Widthbmp * Width * 8;
 
pRGBData = (unsigned char*)malloc(unDataBytes);
memset(pRGBData, 0xff, unDataBytes);
 
BITMAPFILEHEADER BmpHeader;
BmpHeader.bfType = 0x4d42;  // "BM"
BmpHeader.bfSize = sizeof(BITMAPFILEHEADER) +
    sizeof(BITMAPINFOHEADER) +
    unDataBytes;
BmpHeader.bfReserved1 = 0;
BmpHeader.bfReserved2 = 0;
BmpHeader.bfOffBits = sizeof(BITMAPFILEHEADER) +
    sizeof(BITMAPINFOHEADER);
BITMAPINFOHEADER InfoHeader;
InfoHeader.biSize = sizeof(BITMAPINFOHEADER);
InfoHeader.biWidth = Width * 8;
InfoHeader.biHeight = -((int)Width * 8);
InfoHeader.biPlanes = 1;
InfoHeader.biBitCount = 24;
InfoHeader.biCompression = BI_RGB;
InfoHeader.biSizeImage = 0;
InfoHeader.biXPelsPerMeter = 0;
InfoHeader.biYPelsPerMeter = 0;
InfoHeader.biClrUsed = 0;
InfoHeader.biClrImportant = 0;
pSourceData = pQRC->data;
for (y = 0; y < Width; y++)
{
    pDestData = pRGBData + Widthbmp * y * 8;
    for (x = 0; x < Width; x++)
    {
       if (*pSourceData & 1)
       {
           for (l = 0; l < 8; l++)
           {
              for (n = 0; n < 8; n++)
              {
                  *(pDestData + n * 3 + Widthbmp * l) = 0;
                  *(pDestData + 1 + n * 3 + Widthbmp * l) = 0;
                  *(pDestData + 2 + n * 3 + Widthbmp * l) = 0;
              }
           }
       }
       pDestData += 3 * 8;
       pSourceData++;
    }
}
 
if (!(fopen_s(&f, "test.bmp", "wb")))
{
    fwrite(&BmpHeader, sizeof(BITMAPFILEHEADER), 1, f);
    fwrite(&InfoHeader, sizeof(BITMAPINFOHEADER), 1, f);
    fwrite(pRGBData, sizeof(unsigned char), unDataBytes, f);
    fclose(f);
}
       
free(pRGBData);
QRcode_free(pQRC);


其它


  因为二维码拥有校正功能,所以可以遮挡一部分内容同时不影响识别。常见的二维码中,很多都在中心部位添加上一个自定义的logo,用户可以可以根据自身项目需求直接添加,不需要增加其它操作。


  英创提供了文章内所述程序及源代码,有需要的客户可以联系英创工程师获得。

[lablebox]