【发布时间】:2020-08-25 08:27:12
【问题描述】:
我有一个函数可以获取数据并将 .BMP 文件创建为二维码。
int CreateBmpFile(std::wstring barcode)
{
const std::string data(barcode.begin(), barcode.end());
//const char* data;
char* szSourceSring = (char*)data.c_str();
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_L, QR_MODE_8, 1))
//if(pQRC=QRcode_encodeString8bit(szSourceSring,0,QR_ECLEVEL_L))
{
unWidth = pQRC->width;
unWidthAdjusted = unWidth * OUT_FILE_PIXEL_PRESCALER * 3;
if (unWidthAdjusted % 4)
unWidthAdjusted = (unWidthAdjusted / 4 + 1) * 4;
unDataBytes = unWidthAdjusted * unWidth * OUT_FILE_PIXEL_PRESCALER;
// 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 * OUT_FILE_PIXEL_PRESCALER;
kInfoHeader.biHeight = -((int)unWidth * OUT_FILE_PIXEL_PRESCALER);
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 * OUT_FILE_PIXEL_PRESCALER;
for (x = 0; x < unWidth; x++)
{
if (*pSourceData & 1)
{
for (l = 0; l < OUT_FILE_PIXEL_PRESCALER; l++)
{
for (n = 0; n < OUT_FILE_PIXEL_PRESCALER; n++)
{
*(pDestData + n * 3 + unWidthAdjusted * l) = PIXEL_COLOR_B;
*(pDestData + 1 + n * 3 + unWidthAdjusted * l) = PIXEL_COLOR_G;
*(pDestData + 2 + n * 3 + unWidthAdjusted * l) = PIXEL_COLOR_R;
}
}
}
pDestData += 3 * OUT_FILE_PIXEL_PRESCALER;
pSourceData++;
}
}
// Output the bmp file
if (!(fopen_s(&f, OUT_FILE, "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);
}
return 0;
}
调用此函数后,我的bmp文件创建,我可以在windows中打开显示。
如果我想加载它并通过以下代码在我的 win32 对话框中显示:
HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, L"samanqrcode.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE | LR_CREATEDIBSECTION | LR_SHARED);
DWORD err = GetLastError();
WCHAR szTest[10];
swprintf_s(szTest, 10, L"%d", err);
if(hBitmap == NULL)
::MessageBox(_hWnd, szTest, L"rrrrrrr", 0);
if (SUCCEEDED(hr))
{
_Image_Barcode = ::CreateWindow(_T("STATIC"), _T(""),
WS_CHILD | WS_VISIBLE | SS_BITMAP,
85, 70, 230, 230,
_hWnd,
(HMENU)IDI_BARCODE_IMAGE,
_hinst,
NULL);
if (_Image_Barcode == NULL)
hr = HRESULT_FROM_WIN32(::GetLastError());
}
::SendMessage(_Image_Barcode, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap);
LoadImage函数返回NULL,错误码为0。
如果我在 LoadImage 函数中使用其他文件名(任何 bmp 文件,例如由 windows 中的绘图应用程序或其他...创建的任何 bmp 文件),bmp 文件将正确显示。
我创建bmp文件的方法不正确吗?
编辑:
这个问题就像我的问题。 LoadImage() with QRCode bitmap failing unless file is opened/saved with MS Paint first
评论中的用户说:@AbhilashAruva 嗨,谢谢回复。我对 C++ 中的这些图像很陌生。我找到了解决此问题的解决方法。我正在从我的库中生成 JPEG 格式的图像,然后使用 gdi+ 将此图像转换为 bmp 格式。 loadImage 函数现在能够加载新的 bmp 图像。感谢所有的帮助。 – Abhilash Aruva 2014 年 10 月 8 日 7:40
他是我的什么?我无法实现他的方法。
【问题讨论】:
-
我会尝试的第一件事是在位图编辑工具(例如画图)中查看您的位图。如果它无法查看您的位图,那么您就知道它有问题。
-
@john: 我的 bmp 文件创建并且我可以在窗口中打开它来显示 似乎表明海报已经这样做了,不是吗?
-
我在paint和windows查看器中成功打开了这个文件。
-
好的,很明显文件是正确的。抱歉没有仔细阅读。 LoadImage 失败的最常见原因是程序在与程序员放置文件的位置不同的位置查找文件。
-
@john: 如果 LoadImage 函数找不到文件或路径文件,则返回错误 2。如果我更改了文件名,则返回错误。