二维码分类及简介: https://blog.csdn.net/qq_29110265/article/details/86521156
QR Code二维码详解: https://coolshell.cn/articles/10590.html
https://blog.csdn.net/liulina603/article/details/42099121
1、说明:
libqrencode是一个C语言编写的用来生成二维条形码的库,生成的二维条形码可以通过手机的CCD摄像机轻易的扫描出来。此库生成的二维码的容量多达7000个数字或4000个字符,并且具有很强的鲁棒性。
qrencode接受字符串或数据块列表,然后在QR Code符号中编码为位图数组。当其他QR Code应用程序生成图像文件时,使用libqrencode允许应用程序直接从原始位图数据中呈现QR Code符号。该库还包含一个命令行实用程序,可输出各种格式的QR Code图像。
2、规格
qrencode支持JIS(日本工业标准)X0510:2004或ISO / IEC 18004中描述的QR Code模型2。
该规范中的大多数功能都已实现,例如:
- 可以嵌入数字,字母,日语汉字(Shift-JIS)或任何8位代码
- 优化的字符串编码
- 符号的结构化追加
- 微型QR码(实验性)
当前不支持以下功能:
- ECI和FNC1模式
- QR Code模型1(不建议使用)
3、使用(qt为例)
(1)源代码获取(库)
项目链接(github):https://github.com/fukuchi/libqrencode
上面github项目为libqrencode的开发版本。
官方的稳定版本,参见https://fukuchi.org/works/qrencode/,然后就是说明最新版本是多少。
(2)添加到自己的项目中
首先将上面下载的源代码中的有用文件拷贝到项目的一个子目录下(自己定义)。
库代码是c语言写的,然后直接按自己习惯操作,将上面的c库添加到自己的工程项目中,和自己的项目一起编译。
(3)demo代码
主要使用如下函数对内容进行编码:
QRcode* qr = QRcode_encodeString(s.toUtf8(), 1, QR_ECLEVEL_Q, QR_MODE_8, 0);
函数原型:
qt将编码的数据转为QImage,和编码一起封装为函数,代码如下:
QImage encodeImage(const QString& s, int bulk)
{
QImage ret;
QRcode* qr = QRcode_encodeString(s.toUtf8(), 1, QR_ECLEVEL_Q, QR_MODE_8, 0);
if ( qr != nullptr )
{
int allBulk = (qr->width) * bulk;
ret = QImage(allBulk, allBulk, QImage::Format_Mono);
QPainter painter(&ret);
QColor fg("black");
QColor bg("white");
painter.setBrush(bg);
painter.setPen(Qt::NoPen);
painter.drawRect(0, 0, allBulk, allBulk);
painter.setBrush(fg);
for( int y=0; y<qr->width; y++ )
{
for( int x=0; x<qr->width; x++ )
{
if ( qr->data[y*qr->width+x] & 1 )
{
QRectF r(x*bulk, y*bulk, bulk, bulk);
painter.drawRects(&r, 1);
}
}
}
QRcode_free(qr);
}
return ret;
}
如果是使用的标准库,可以使用如下函数将二维码信息生成bmp格式的二维码图片。
void qr_code(std::string _src_str, std::string _dst_bmp_path)
{
//参数_src_str是待编码的字符串,_dst_bmp_path是编成二维码后生成的bmp路径名,比如 ./my_qrcode.bmp
const char* szSourceSring = _src_str.c_str();
unsigned int unWidth, x, y, l, n, unWidthAdjusted, unDataBytes;
unsigned char* pRGBData, *pSourceData, *pDestData;
QRcode* pQRC;
FILE* f;
if (pQRC = QRcode_encodeString(szSourceSring, 0, QR_ECLEVEL_H, QR_MODE_8, 1))
{
unWidth = pQRC->width;
unWidthAdjusted = unWidth * 8 * 3;
if (unWidthAdjusted % 4)
unWidthAdjusted = (unWidthAdjusted / 4 + 1) * 4;
unDataBytes = unWidthAdjusted * unWidth * 8;
// Allocate pixels buffer
if (!(pRGBData = (unsigned char*)malloc(unDataBytes)))
{
exit(-1);
}
// Preset to white
memset(pRGBData, 0xff, unDataBytes);
// Prepare bmp headers
BITMAPFILEHEADER kFileHeader;
kFileHeader.bfType = 0x4d42; // "BM"
kFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + unDataBytes;
kFileHeader.bfReserved1 = 0;
kFileHeader.bfReserved2 = 0;
kFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
BITMAPINFOHEADER kInfoHeader;
kInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
kInfoHeader.biWidth = unWidth * 8;
kInfoHeader.biHeight = -((int)unWidth * 8);
kInfoHeader.biPlanes = 1;
kInfoHeader.biBitCount = 24;
kInfoHeader.biCompression = BI_RGB;
kInfoHeader.biSizeImage = 0;
kInfoHeader.biXPelsPerMeter = 0;
kInfoHeader.biYPelsPerMeter = 0;
kInfoHeader.biClrUsed = 0;
kInfoHeader.biClrImportant = 0;
// Convert QrCode bits to bmp pixels
pSourceData = pQRC->data;
for (y = 0; y < unWidth; y++)
{
pDestData = pRGBData + unWidthAdjusted * y * 8;
for (x = 0; x < unWidth; x++)
{
if (*pSourceData & 1)
{
for (l = 0; l < 8; l++)
{
for (n = 0; n < 8; n++)
{
//以下三行是设置三基色,三基色都设置为0x00,则生成的二维码图片就是黑色的了,要什么颜色自己调整
*(pDestData + n * 3 + unWidthAdjusted * l) = 0x00;
*(pDestData + 1 + n * 3 + unWidthAdjusted * l) = 0x00;
*(pDestData + 2 + n * 3 + unWidthAdjusted * l) = 0x00;
}
}
}
pDestData += 3 * 8;
pSourceData++;
}
}
// Output the bmp file
if (!(fopen_s(&f, _dst_bmp_path.c_str(), "wb")))
{
fwrite(&kFileHeader, sizeof(BITMAPFILEHEADER), 1, f);
fwrite(&kInfoHeader, sizeof(BITMAPINFOHEADER), 1, f);
fwrite(pRGBData, sizeof(unsigned char), unDataBytes, f);
printf("qrcode has generated in %s\n", _dst_bmp_path.c_str());
fclose(f);
}
else
{
printf("Unable to open file");
exit(-1);
}
// Free data
free(pRGBData);
QRcode_free(pQRC);
}
else
{
printf("NULL returned");
exit(-1);
}
}