C++ - 创建 bmp 文件并通过 createwindow() 显示它的问题
C++ - Problem with create bmp file and show it by createwindow()
我有一个函数可以获取数据并创建 .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 函数return NULL,错误代码为 0。
如果我在 LoadImage 函数中使用其他文件名(例如由 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 14 年 10 月 8 日 7:40
他是我的什么?我无法实现他的方法。
我找到了解决办法。使用from gdi+将bmp转jpg,将jpg转bmp。
我有一个函数可以获取数据并创建 .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 函数return NULL,错误代码为 0。
如果我在 LoadImage 函数中使用其他文件名(例如由 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 14 年 10 月 8 日 7:40
他是我的什么?我无法实现他的方法。
我找到了解决办法。使用from gdi+将bmp转jpg,将jpg转bmp。