MFC BitBlt and SetDIBits vs. SetBitmapBits
MFC BitBlt and SetDIBits vs. SetBitmapBits
我有一个存储为BGRA字节数组的位图。这是我用来绘制位图的代码:
CDC *dispDC = new CDC();
dispDC->CreateCompatibleDC(pDC);
CBitmap *dispBMP = new CBitmap();
dispBMP->CreateCompatibleBitmap(pDC, sourceImage->GetWidth(), sourceImage->GetHeight());
dispDC->SelectObject(this->dispBMP);
translatedImage
数组中像素的实际复制是这样进行的:
dispBMP->SetBitmapBits(sourceImage->GetArea() * 4, translatedImage);
然后经过一些更多的处理,我调用pDC->StretchBlt
与dispDC
作为源CDC。这在本地登录时可以正常工作,因为显示也设置为32bpp。
一旦我登录远程桌面,显示到16bpp,图像是混乱的。罪魁祸首是SetBitmapBits
;也就是说,为了让它工作,我必须正确地填充translatedImage
与我想要显示的16bpp版本。而不是自己这样做,我搜索了文档,发现SetDIBits
听起来像我想要的:
SetDIBits函数使用在指定的DIB中找到的颜色数据在兼容位图(DDB)中设置像素。
在我的例子中,DIB是32bpp RGBA数组,DDB是我用CreateCompatibleBitmap
创建的dispBMP
。
所以我没有调用SetBitmapBits
,而是这样做:
BITMAPINFO info;
ZeroMemory(&info, sizeof(BITMAPINFO));
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biBitCount = 32;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biCompression = BI_RGB;
info.bmiHeader.biSizeImage = sourceImage->GetArea()*4;
info.bmiHeader.biWidth = sourceImage->GetWidth();
info.bmiHeader.biHeight = sourceImage->GetHeight();
info.bmiHeader.biClrUsed = 0;
int r = SetDIBits(pDC->GetSafeHdc(), (HBITMAP)dispBMP,
0, sourceImage->GetHeight(), translatedImage,
&info, DIB_PAL_COLORS);
然而,r
总是零,自然地,我得到的只是黑色的窗口。代码有什么问题?
根据SetDIBits
的文档:
不能选择hbmp参数标识的位图应用程序调用此函数时的设备上下文。
在您的示例代码中,您在创建它后将其选择到设备上下文中,因此可能这就是SetDIBits
失败的原因。
Ross Ridge指出的代码顺序错误是正确的。然而,这并没有解决问题。
问题出在我传递的参数上。我是c++和MFC的新手,经常忘记所有可以作用于类型以自动转换它们的"操作符"。
之前我有这个:
int r = SetDIBits(pDC->GetSafeHdc(), (HBITMAP)dispBMP,
0, sourceImage->GetHeight(), translatedImage,
&info, DIB_PAL_COLORS);
正确的调用是:
int r = SetDIBits(*pDC, *dispBMP,
0, sourceImage->GetHeight(), translatedImage,
&info, DIB_PAL_COLORS);
(注意,我在前两个形参中传递了未引用指针。)其他一切都是正确的,包括反直觉的DIB_PAL_COLORS
标志位图没有调色板。
在明显错过了文档中的一些关键点之后,我重新阅读了它,然后发现了这个示例代码,显示我只是错误地传递了参数。
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 数据成员SFINAE的C++17测试:gcc vs clang
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 正在VS调试器中监视映射条目
- Confusion: decltype vs std::function
- 将IBM Rhapsody模型集成到VS 2019中
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 使用VS Code和CMake Tools运行自定义命令
- 修改 VS Code 中的默认C++代码段
- 如何使用c++在VS 2019上运行SQL查询
- vs 2015 constexpr变量不恒定,但与2019相比还好吗
- 完美前进使用 std::forward vs RefRefCast
- 从VS 2015更新3更新到VS2015更新3 d后浮点计算行为不同的原因
- VS 2015 链接错误 无法构建依赖于 libcurl 的项目
- consteval wrapper vs. source_location
- VS Code C++:不准确的系统包括路径错误(wchar.h,boost/lambda/lambda.hpp)
- QStringList vs list<shared_ptr<QString>> 性能比较C++
- MFC BitBlt and SetDIBits vs. SetBitmapBits