- qrencode 源码下载地址 https://fukuchi.org/works/qrencode/
我下载的是 qrencode-4.0.2.tar.gz 版本 - 用cmake跨平台编译工具,生成vs解决方案
- 解压 qrencode-4.0.2.tar.gz, 使用cmd命令打开命令行,进入源码目录,执行以下操作:
cmake . -DGETOPT_INCLUDE_DIR=“库头文件所在目录” -DGETOPT_LIBRARIES=“库文件所在目录”
注: 该库的示例代码(qrenc工程)中使用了libpng库生成二维码图片,libpng库依赖zlib库,需要使用qrenc的童鞋们请先编译对应的依赖库。我扎边直接生成bmp格式的图片就不需要链接以上两个库了。 - 我这边没有链接libpng和zlib库。则跳过第三步, 直接使用命令:cmake . -DGETOPT_INCLUDE_DIR="" -DGETOPT_LIBRARIES=""
敲回车键执行如下:
完成结果如下:
5.至此,我们已经用cmake生成了vs的解决方案,是不是很简单呢。下面我们进入到源码目录D:\We\qrencode-4.0.2 找到QRencode.sln双击打开,我这边使用的是Visual Studio 14 2015版本
打开项目如下:
注:直接编译会提示失败,这个是因为全部编译的时候qrenc项目中缺少libpng和zlib相关依赖库。其实我们真正需要的项目是 qrencode 这个项目。qrencode是静态库工程,单独编译后生成qrencode.lib。 - 到这里qrencode.lib就真正得到啦,你可以新建工程链接该qrencode.lib库,将头文件(qrencode.h)复制到项目下,调用一下代码生成bmp二维码图片:
void qr_code(std::string _src_str, std::string _dst_bmp_path)
{
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;
if (!(pRGBData = (unsigned char*)malloc(unDataBytes))) {
std::cout << "malloc err" << std::endl;
exit(-1);
}
memset(pRGBData, 0xff, unDataBytes);
BITMAPFILEHEADER kFileHeader;
kFileHeader.bfType = 0x4d42;
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;
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++)
{
*(pDestData + n * 3 + unWidthAdjusted*l) = 0xff;
*(pDestData + 1 + n * 3 + unWidthAdjusted*l) = 0x00;
*(pDestData + 2 + n * 3 + unWidthAdjusted*l) = 0x00;
}
}
}
pDestData += 3 * 8;
pSourceData++;
}
}
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);
std::cout << "qrcode has generated in " << _dst_bmp_path.c_str() << std::endl;
fclose(f);
}
else
{
std::cout << "unable to open file" << std::endl;
exit(-1);
}
free(pRGBData);
QRcode_free(pQRC);
}
else
{
std::cout << "NULL returned" << std::endl;
exit(-1);
}
}