16,472
社区成员
发帖
与我相关
我的任务
分享
bool Make2DBarCodeBmp(const wchar_t* nswCodeContent, const wchar_t* nswBmpFile, UINT nuiZoomIn)
{
if(NULL == nswCodeContent || NULL == nswBmpFile)
return false;
bool lbRet = false;
pdf417param ldPdf417Info = {0};
do
{
// 构造数据
pdf417init(&ldPdf417Info);
ldPdf417Info.text = UnicodeToAnsi(nswCodeContent);
ldPdf417Info.options = PDF417_INVERT_BITMAP;
paintCode(&ldPdf417Info);
if(PDF417_ERROR_SUCCESS != ldPdf417Info.error)
{
pdf417free(&ldPdf417Info);
break;
}
// -------------------------------------------------------------------------------------------------------------------------------
// 8位位图,一个像素占据一位,方便缩放处理
// -------------------------------------------------------------------------------------------------------------------------------
// 放大倍数
int liZoomInX = nuiZoomIn;
int liZoomInY = nuiZoomIn;
// 将ldPdf417Info.lenBits中以位为单位的总字节数为ldPdf417Info.outBits的像素值转换成以字节为单位的像素值
ULONG lulPixelWidth = ldPdf417Info.bitColumns * liZoomInX;
ULONG lulPixelHeight = ldPdf417Info.codeRows * liZoomInY;
ULONG lulBmpWidth = ldPdf417Info.lenBits * 8 / ldPdf417Info.codeRows * liZoomInX; // 因为BMP图存储时数据部分必须四字节对齐,所以Bmp图宽度和像素宽度不一定相同,拷贝数据的时候要以BMP图宽度为准
ULONG lulCbRealDataWithoutRepeatRows = ldPdf417Info.lenBits * 8 * liZoomInX; // 除去了重复行的有效数据字节数
PBYTE lpPixelData = new BYTE[lulCbRealDataWithoutRepeatRows]; // 扩充X倍
RtlZeroMemory(lpPixelData, lulCbRealDataWithoutRepeatRows);
// 扩充后的白色像素点数据
ULONG lulRateX = 1 * liZoomInX; // 放大后水平方向上之前每字节对应现在多少个字节
PBYTE lpWhiteColorData = new BYTE[lulRateX];
memset(lpWhiteColorData, 0xFF, lulRateX);
BYTE lbBitMask = 0x80;
PBYTE lpCrtPos = lpPixelData;
for(int i = 0; i < ldPdf417Info.lenBits * 8; ++i)
{
if(ldPdf417Info.outBits[i / 8] & lbBitMask)
{
RtlCopyMemory(lpCrtPos, lpWhiteColorData, lulRateX);
}
lpCrtPos += lulRateX;
lbBitMask = lbBitMask >> 1;
if(lbBitMask == 0)
lbBitMask = 0x80;
}
SAFE_DELETE(lpWhiteColorData);
// 位图信息头
BITMAPINFOHEADER ldBmpInfoHeader = {0};
ldBmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
ldBmpInfoHeader.biWidth = lulPixelWidth;
ldBmpInfoHeader.biHeight = lulPixelHeight;
ldBmpInfoHeader.biPlanes = 1;
ldBmpInfoHeader.biBitCount = 8;
ldBmpInfoHeader.biCompression = BI_RGB;
ldBmpInfoHeader.biSizeImage = 0;
ldBmpInfoHeader.biXPelsPerMeter = 0;
ldBmpInfoHeader.biYPelsPerMeter = 0;
ldBmpInfoHeader.biClrUsed = 0;
ldBmpInfoHeader.biClrImportant = 0;
// 位图文件头
BITMAPFILEHEADER ldBmpFileHeader = {0};
ldBmpFileHeader.bfType = 0x4D42; // "BM"
ldBmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD); // 数据部分偏移
LONG llCbPerRow = ldBmpInfoHeader.biWidth + (ldBmpInfoHeader.biWidth % 4 > 0 ? 4 - ldBmpInfoHeader.biWidth % 4 : 0); // 每行实际占据的字节数(四字节对齐)
LONG llCbData = llCbPerRow * ldBmpInfoHeader.biHeight; // 数据总共占据的字节数
ldBmpFileHeader.bfSize = ldBmpFileHeader.bfOffBits + llCbData;
// 颜色表
RGBQUAD ldColorTable[256] = {{0,0,0,0},{255,255,255,0}};
for(int i = 0; i < 256; ++i)
{
ldColorTable[i].rgbBlue = i;
ldColorTable[i].rgbGreen = i;
ldColorTable[i].rgbRed = i;
ldColorTable[i].rgbReserved = 0;
}
// 构建位图
HANDLE lhFile = CreateFile(nswBmpFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(NULL == lhFile)
{
break;
}
DWORD ldwCbWritten = 0;
WriteFile(lhFile, (LPVOID)&ldBmpFileHeader, sizeof(BITMAPFILEHEADER), &ldwCbWritten, NULL);
WriteFile(lhFile, (LPVOID)&ldBmpInfoHeader, ldBmpInfoHeader.biSize, &ldwCbWritten, NULL);
WriteFile(lhFile, (LPVOID)&ldColorTable, 256 * sizeof(RGBQUAD), &ldwCbWritten, NULL);
// 每行为了对齐所需要填充的数据
ULONG lulCbForFill = llCbPerRow -ldBmpInfoHeader.biWidth;
PBYTE lpDataForFill = NULL;
if(lulCbForFill > 0)
{
lpDataForFill = new BYTE[lulCbForFill];
RtlZeroMemory(lpDataForFill, lulCbForFill);
}
// 每行实际数据缓冲
for(int i = 0; i < ldBmpInfoHeader.biHeight / liZoomInY; ++i)
{
for(int y = 0; y < liZoomInY; ++y)
{
WriteFile(lhFile, (LPVOID)&lpPixelData[i * lulBmpWidth], lulPixelWidth, &ldwCbWritten, NULL);
if(lulCbForFill > 0)
WriteFile(lhFile, (LPVOID)lpDataForFill, lulCbForFill, &ldwCbWritten, NULL);
}
}
SAFE_DELETE(lpPixelData);
SAFE_DELETE(lpDataForFill);
CloseHandle(lhFile);
lbRet = true;
} while (false);
if(NULL != ldPdf417Info.text)
delete ldPdf417Info.text;
pdf417free(&ldPdf417Info);
return lbRet;
}