我有一个位图存储为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
作为源CDC调用dispDC
。这在本地登录时工作正常,因为显示也设置为32bpp。
一旦我使用远程桌面登录,显示屏将变为16bpp并且图像被破坏。罪魁祸首是SetBitmapBits
;即为了它的工作,我必须正确填写translatedImage
我想要显示的16bpp版本。我没有自己这样做,而是搜索了文档,发现SetDIBits
听起来像我想要的那样:
SetDIBits函数使用在指定DIB中找到的颜色数据设置兼容位图(DDB)中的像素。
就我而言,DIB是32bpp RGBA数组,DDB是dispBMP
,我使用CreateCompatibleBitmap
创建。{/ p>
所以不是我对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
总是为零,当然,我的窗户里只有黑色。代码有什么问题?
答案 0 :(得分:5)
根据documentation for SetDIBits
:
不得将hbmp参数标识的位图选入a 应用程序调用此函数时的设备上下文。
在您的示例代码中,您在创建它之后将其选择到设备上下文中,因此可能是SetDIBits
失败的原因。
答案 1 :(得分:2)
罗斯里奇指出代码顺序错误是正确的。但是,这并没有解决问题。
问题在于我传递的参数。我是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
标志。
在显然遗漏了文档中的一些关键点后,我重新阅读了它,然后发现this的示例代码显示我只是错误地传递了参数。