因为毕设的要求,需要根据一串字符串生成二维码,然后语言里面我只会c/c++,所以只能根据c/c++生成二维码,搜了很久,发现了一个c语言二维码库libqrencode,不过这个库得下载下来,我这边采用的是编译成静态库使用,这边文章里就讲述一下libqrencode库的编译过程及使用。
libqrencode下载地址:http://pan.baidu.com/s/1pLsI2DH
工具:VS2013
先建立一个win32控制台应用程序,不需要预编译头(空项目),静态库,这边取名QRtest,然后把libqrencode里面所有的.h、.c文件都添加到项目里(这边我提供下载的libqrencode库已经把qrenc.c删掉了,实际在官网下载的libqrencode包含qrenc.c但是却不需要使用,所以为了方便我直接删了它)
右击项目,选择属性,然后在预处理器定义里添加:HAVE_CONFIG_H
修改方法如下:打开split.c文件,修改里面的strdup为全部mystrdup,不修改的话会和标准库里的strdup混淆
修改之后在运行,结果如下:
可以看到最下面一行输出,生成一个,失败0个;打开debug文件,发现已经生成库文件了。
接下来讲一下这个静态库的使用:
首先简历一个vs2013空项目,这边取名为二维码测试:
然后把之前生成的QRtest.lib及头文件qrencode.h放入项目文件里:
上程序测试:
#include
#include
#include
#include
#include
#include
#include
#include
#include "qrencode.h"
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef signed long LONG;
#define BI_RGB 0L
#pragma pack(push, 2)
typedef struct
{
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
typedef struct
{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
#pragma pack(pop)
// -------------------------------------------------------
// -------------------------------------------------------
// Main
// -------------------------------------------------------
int main()
{
char szSourceSring[100] = "12345678"; //生成二维码的字符串
unsigned int unWidth, x, y, l, n, unWidthAdjusted, unDataBytes;
unsigned char* pRGBData, *pSourceData, *pDestData;
QRcode* pQRC;
FILE* f;
// Compute QRCode
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)))
{
printf("Out of memory");
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++)
{
*(pDestData + n * 3 + unWidthAdjusted * l) = 0;
*(pDestData + 1 + n * 3 + unWidthAdjusted * l) = 0;
*(pDestData + 2 + n * 3 + unWidthAdjusted * l) = 0;
}
}
}
pDestData += 3 * 8;
pSourceData++;
}
}
// Output the bmp file
if (!(fopen_s(&f, "二维码.bmp", "wb")))
{
fwrite(&kFileHeader, sizeof(BITMAPFILEHEADER), 1, f);
fwrite(&kInfoHeader, sizeof(BITMAPINFOHEADER), 1, f);
fwrite(pRGBData, sizeof(unsigned char), unDataBytes, f);
fclose(f);
}
else
{
printf("Unable to open file");
exit(-1);
}
// Free data
free(pRGBData);
QRcode_free(pQRC);
}
else
{
printf("NULL returned");
exit(-1);
}
system("pause");
return 0;
}
程序运行完之后,发现项目文件里生成了二维码:
为了验证二维码的正确生成与否,可以用微信扫一扫,发现扫出来的字符串和我程序里设定的字符串一致!
关于二维码的解码,可以参考http://blog.csdn.net/dcrmg/article/details/52108258
http://blog.csdn.net/dcrmg/article/details/51809614这两篇文章!