gpt4 book ai didi

c++ - 如何使 8 位位图在 C++ 中显示为单色?

转载 作者:太空狗 更新时间:2023-10-29 20:05:11 25 4
gpt4 key购买 nike

当我像这样设置和创建 24 位位图时:

   //fileheader
BITMAPFILEHEADER* bf = new BITMAPFILEHEADER;
bf->bfType = 0x4d42;
bf->bfSize = 6054400 + 54;
bf->bfOffBits = 54;

//infoheader
BITMAPINFOHEADER* bi = new BITMAPINFOHEADER;
bi->biSize = 40;
bi->biWidth = 2752;
bi->biHeight = -733;
bi->biPlanes = 1;
bi->biBitCount = 24;
bi->biCompression = 0;
//bi->biSizeImage = 6054400;
bi->biXPelsPerMeter = 2835;
bi->biYPelsPerMeter = 2835;
bi->biClrUsed = 0;
bi->biClrImportant = 0;

pFrame->GetImage(m_imageData);

//
//create bitmap...
//(hbit is a global variable)

BITMAPINFO* bmi;
bmi = (BITMAPINFO*)bi;
HDC hdc = ::GetDC(NULL);

hbit = CreateDIBitmap(hdc, bi, CBM_INIT, m_imageData, bmi, DIB_RGB_COLORS);

我得到这样的输出图像: image1

但是当我将位计数从 24 更改为 8(这也允许 3 倍的图像大小,允许我从 733 宽度变为图像的自然宽度 2200)时,我得到了这样的图像(伴随着很多不稳定性) ):

image2

我的输出看起来像这样:

    BITMAP* bi = new BITMAP;
CBitmap bmp;
bmp.Attach(hbit);
CClientDC dc(pWnd);
CDC bmDC;
bmDC.CreateCompatibleDC(&dc);
CBitmap *pOldbmp = bmDC.SelectObject(&bmp);
bmp.GetBitmap(bi);
dc.BitBlt(384,26,bi->bmWidth/3,bi->bmHeight,&bmDC,0,0,SRCCOPY);
//note: if bitcount is 8, height and width need to be /3,
//if 24, only width gets /3
bmDC.SelectObject(pOldbmp);

//explicitly delete everything just to be safe
delete bi;
DeleteObject(bmp);
DeleteObject(dc);
DeleteObject(pOldbmp);
DeleteObject(bmDC);

所以我的问题是:

  • 当我从 24 岁切换到 8 岁时,为什么会发生这种情况?
  • 有没有一种简单的方法可以将图像输出为单色而不是彩色?

最后一件事:

我的同事很久以前就类似的问题写了这个功能,但他说我也许可以用它。不幸的是,我无法让它工作:

void CopyMono8ToBgrx(byte* pDestBlue, byte* pDestGreen, byte *pDestRed, byte* pDestAlpha)
{
byte* pSrc;
byte* pSrcEnd;

pSrc = ( byte* ) m_imageData;
pSrcEnd = pSrc + ( 2752*2200 );

while ( pSrc < pSrcEnd )
{
byte data = *pSrc;

*pDestBlue = data;
*pDestGreen = data;
*pDestRed = data;
*pDestAlpha = 255; // alpha is always 255 (fully opaque)

pSrc++;
pDestBlue += 4;
pDestGreen += 4;
pDestRed += 4;
pDestAlpha += 4;
}
}

最佳答案

您应该创建一个调色板。试试这个:

struct BITMAPINFO256 {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[256];
} bmi;
memset(&bmi, 0, sizeof(BITMAPINFO256));
bmi.bmiHeader.biSize = 40;
bmi.bmiHeader.biWidth = 2752;
bmi.bmiHeader.biHeight = -733;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 8;
bmi.bmiHeader.biCompression = 0;
bmi.bmiHeader.biXPelsPerMeter = 2835;
bmi.bmiHeader.biYPelsPerMeter = 2835;
bmi.bmiHeader.biClrUsed = 256;
bmi.bmiHeader.biClrImportant = 0;
for (unsigned int i = 0; i < 256; i++) {
bmi.bmiColors[i].rgbRed = i;
bmi.bmiColors[i].rgbGreen = i;
bmi.bmiColors[i].rgbBlue = i;
}

然后当您调用 CreateDIBitmap 时,它将变为:

hbit = CreateDIBitmap(hdc, &bmi.bmiHeader, CBM_INIT, m_imageData, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);

另请注意,您还应该小心地增加 BITMAPFILEHEADER 中的偏移量,以便它表示在实际像素数据之前定义了颜色调色板(昨天我遇到了困难,因为这个,参见 Creating 8bpp bitmap with GDI and saving it as a file ):

bf->bfOffBits = 54 + sizeof(RGBQUAD)*256;

对于您的同事写的那个函数:最好使用 Luminance将颜色转换为灰度等效值: enter image description here

希望这有帮助:)

关于c++ - 如何使 8 位位图在 C++ 中显示为单色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14876685/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com