MFC - 如何将颜色位图绘制到对话框DC

时间:2014-11-07 23:49:15

标签: c++ opencv visual-c++ bitmap mfc

我在相机采集循环中获得了这段代码:

CBitmap* bmp = new CBitmap();
CDC* pDC;
CBitmap* old;
CDC*  memDC = new CDC();

pDC = pLiveImageDlg->GetDC();

bmp->CreateCompatibleBitmap(pDC, 640, 480);

memDC->CreateCompatibleDC(pDC);
old = memDC->SelectObject(bmp);

bmp->SetBitmapBits(640 * 480 * 3, frame.data);

pDC->BitBlt(0, 0, 640, 480, memDC, 0, 0, SRCCOPY);

memDC->SelectObject(old);

我的问题是,当查看被绘制到对话框上的位图时,它看起来完全失真和单色。通常,图像失真意味着像素索引关闭(错误的颜色格式等)。 "框架"变量是一个OpenCV Mat对象,它将图像作为24位RGB格式抓取(使用imshow()显示完美的颜色)。我觉得单色问题与CreateCompatibleDC函数调用有关,因为根据MSDN文档,默认情况下会创建1x1单色像素...而这个单色问题可能会导致"像素字节数组偏移"问题。

将位图作为24位RGB位图显示在屏幕上的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

是的,你是对的 - 默认是单色的。 我认为最简单的(也是最快的GDI)只是直接渲染24位图:

BITMAPINFO bmi = { 0 };
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = 640;
bmi.bmiHeader.biHeight = -480;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;

CClientDC dc(pLiveImageDlg);
SetDIBitsToDevice(dc, 0, 0, 640, 480, 0, 0, 0, 480, data, frame.data, 0);

这里要提两件事,应该有正确的RGB序列(即RGB / BGR)和正确的垂直线序列(即向上 - >向下对比向下 - >向上),您可以使用设置biHeight进行调整到正/负值。

答案 1 :(得分:0)

如果要显示灰度位图,则必须在BITMAPINFO中准备调色板

int bpp = 8 * img.elemSize();
uchar buffer[sizeof(BITMAPINFO) + 256*4];
BITMAPINFO* bmi = (BITMAPINFO*)buffer;
BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);

//Sets the palette only if image is grey scale
if (bpp == 8)
{
    RGBQUAD* palette = bmi->bmiColors;
    for (int i = 0; i < 256; i++)
    {
      palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
      palette[i].rgbReserved = 0;
    }
}

请点击此处了解详情:How to display an OpenCV image or video in your own MFC interface