c++ - 从 bmp 文件数据创建 MFC CBitmap
问题描述
我有一个指向从 *.bmp 文件中读取的数据的 void 指针。bmp 文件不再存在(现在有一个文件包含数百个这样的位图文件数据集)。如何CBitmap
使用这些数据初始化 MFC?
我看到了这些CBitmap::Create*
功能(例如 ,CreateBitmap()
等CreateCompatibleBitmap()
),但它们要求我知道位图的高度和宽度,可以访问数据位等。我可以将数据写入磁盘,然后使用::LoadImage()
和CBitmap::Attach()
加载位图,但我想在内存中这样做以提高性能。
谢谢!
更新(#2):
这是我的代码,正如 Constantine Georgiou 的评论和帖子所建议和简化的(谢谢!)。CBitmap::CreateBitmap() 不再失败,但位图显示为黑色。
// Bitmap File Header
LPBITMAPFILEHEADER pFileHdr = (LPBITMAPFILEHEADER)pFileData;
// Bitmap Info Header
LPBITMAPINFOHEADER pBmpHdr = (LPBITMAPINFOHEADER)((PCHAR)pFileData + sizeof(BITMAPFILEHEADER));
// Image Data
LPVOID lpBits = (LPVOID)((PCHAR)pFileData + pFileHdr->bfOffBits);
if(!bitmap.CreateBitmap(pBmpHdr->biWidth, pBmpHdr->biHeight, pBmpHdr->biPlanes, pBmpHdr->biBitCount, lpBits))
bool bummer = true;
这是将相同数据写入文件然后使用 ::LoadImage() 加载位图的代码。这行得通。
CFile file;
if(file.Open(sFilename, CFile::modeCreate | CFile::modeReadWrite))
{
file.Write(pFileData, dwFileBytes);
file.Close();
HBITMAP hBitmap = (HBITMAP)::LoadImage(NULL, sFilename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if(hBitmap)
{
if(!bitmap.Attach(hBitmap))
bool ahHeck = true;
}
}
以下是有关上述内容的跟踪消息。
在创建图像之前检查内存中的文件数据:
dwFileBytes = 3128.
- BMP 标题:
biSize = 40
biWidth = 32
biHeight = 32
biPlans = 1
biBitCount = 24
biCompression = 0
biSizeImage = 3074
调用 CreateBitmap(32, 32, 1, 24, lpBits) 后检查 BITMAP:
bmType = 0
bmWidth = 32
bmHeight = 32
bmPlanes= 1
bmWidthBytes = 96
bmBitsPixel = 24
bmBits = 0
(该位图显示为黑色。)
写入文件并调用 LoadImage() 后检查 BITMAP:
bmType = 0
bmWidth = 32
bmHeight = 32
bmPlanes= 1
bmWidthBytes = 128
bmBitsPixel = 32
bmBits = 0
(此位图正确显示。)
我意识到我正在深入了解细节。道歉!我难住了。
解决方案
您的代码是正确的,尽管我宁愿将其简化一点 - 无需复制这些结构,因为它们已经存在 - 只是一些类型转换和指针算术。例如:
// Bitmap File Header
LPBITMAPFILEHEADER pFileHdr = (LPBITMAPFILEHEADER)pFileData;
// Bitmap Info Header
LPBITMAPINFOHEADER pBmpHdr = (LPBITMAPINFOHEADER)((PCHAR)pFileData + sizeof(BITMAPFILEHEADER));
// Image Data
LPVOID lpBits = (LPVOID)((PCHAR)pFileData + pFileHdr->bfOffBits);
该文档清楚地提到“位数”是每个像素的位数。因此,电话将是:
if (!m_IconBitmap.CreateBitmap(pBmpHdr->biWidth, pBmpHdr->biHeight, pBmpHdr->biPlanes,
pBmpHdr->biBitCount, lpBits))
{
// Handle the Error
}
(还没有真正测试过这段代码,但它应该可以工作)
我不得不提一下,图像格式相当不寻常,即每像素 16 位可能是 BGR 5-5-5 格式(每个组件 5 位)。每个像素两个字节,图像大小应该是 2048 字节(32 x 32 x 2)。像这样由 Microsoft 工具创建的位图文件将是 2102 字节,这是正确的(结构为 54 字节,位图数据为 2048 字节 - 无调色板)。也许您应该将数据存储到文件中并使用十六进制编辑器检查它们。
推荐阅读
- vba - 复制工作表粘贴为值但跳过受保护的单元格
- html - 带有字体真棒图标的 Z-index 不起作用
- image - 如何在不改变像素值的情况下下采样图像数组
- qt - Qt .qrc 在 MSVC2017 与 MinGW 32 中的读取
- javascript - taffyDB 不保存数据
- python - 使用 Python 从 XML 文档中获取特定元素
- html - BEM中block__element__element和block__element-element有什么区别
- python - 无法理解余弦相似度的python函数
- android - 如何防止服务在Android中退出?
- java - Elasticsearch 聚合和按字段求和(分组依据)