各位,CreateDibSection说是返回一个Dib的位图,我们知道dib是与设备无关的,里面包含了调色板等信息。为什么我在网上查的代码都是不用解析这个dib的调色板,再赋给对应的dc,而是直接使用当前的设备调色板。就像下面的代码一样:
void CPalettedDIBView::OnDraw(CDC* pDC)
{
CPalettedDIBDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);struct SIBITMAPINFO
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColor[3]; //exactly three colors in the palette
};SIBITMAPINFO bi = {0};
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = 256;
bi.bmiHeader.biHeight = 256; // positive number == bottom-up DIB
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 8;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biClrUsed = 3; // only three colors are in the palette
// define the three colors in the palette (R, G and B)bi.bmiColor[ 0 ].rgbRed = 255;
bi.bmiColor[ 0 ].rgbGreen = 0;
bi.bmiColor[ 0 ].rgbBlue = 0;
bi.bmiColor[ 0 ].rgbReserved = 0;bi.bmiColor[ 1 ].rgbRed = 0;
bi.bmiColor[ 1 ].rgbGreen = 255;
bi.bmiColor[ 1 ].rgbBlue = 0;
bi.bmiColor[ 1 ].rgbReserved = 0;
bi.bmiColor[ 2 ].rgbRed = 0;
bi.bmiColor[ 2 ].rgbGreen = 0;
bi.bmiColor[ 2 ].rgbBlue = 255;
bi.bmiColor[ 2 ].rgbReserved = 0;
BYTE* pBits;HANDLE hBM = ::CreateDIBSection( (HDC)(*pDC), (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&pBits, 0, 0 );// Set color-index values of the pixels
// This is a bottom-up DIB, so the colors will be in horizontal bands, 64 rows high,
// in the order (bottom-up) of R, G, Bfor ( int iRow=0; iRow<256; ++iRow )
{
for ( int iCol=0; iCol<256; ++iCol )
{
switch ( (iRow/64)%4 )
{
case 0: *pBits = 0; break;
case 1: *pBits = 1; break;
case 2: *pBits = 2; break;
case 3: *pBits = 0; break;
}pBits++;
}
}// blt the DDB bitmap to the display device contextCBitmap bm;
bm.Attach( hBM );CDC memDC;
memDC.CreateCompatibleDC( pDC );
CBitmap* pOldBM = memDC.SelectObject( &bm );pDC->BitBlt( 0, 0, 256, 256, &memDC, 0, 0, SRCCOPY );memDC.SelectObject( pOldBM );}大家可以看到红色部分,我们在上面定义的调色板,然后调用CreateDIBSection返回一个HBitmap,我觉得在memDC中应该把返回的这个HBitmap中的调色板解析出来,再select到memDC中。这样其实就把它当成了一个DDB来操作了,而不是DIB. 但是这个函数返回的是DIB,而不是DDB。哪位大虾能解释一下。
void CPalettedDIBView::OnDraw(CDC* pDC)
{
CPalettedDIBDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);struct SIBITMAPINFO
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColor[3]; //exactly three colors in the palette
};SIBITMAPINFO bi = {0};
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = 256;
bi.bmiHeader.biHeight = 256; // positive number == bottom-up DIB
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 8;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biClrUsed = 3; // only three colors are in the palette
// define the three colors in the palette (R, G and B)bi.bmiColor[ 0 ].rgbRed = 255;
bi.bmiColor[ 0 ].rgbGreen = 0;
bi.bmiColor[ 0 ].rgbBlue = 0;
bi.bmiColor[ 0 ].rgbReserved = 0;bi.bmiColor[ 1 ].rgbRed = 0;
bi.bmiColor[ 1 ].rgbGreen = 255;
bi.bmiColor[ 1 ].rgbBlue = 0;
bi.bmiColor[ 1 ].rgbReserved = 0;
bi.bmiColor[ 2 ].rgbRed = 0;
bi.bmiColor[ 2 ].rgbGreen = 0;
bi.bmiColor[ 2 ].rgbBlue = 255;
bi.bmiColor[ 2 ].rgbReserved = 0;
BYTE* pBits;HANDLE hBM = ::CreateDIBSection( (HDC)(*pDC), (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&pBits, 0, 0 );// Set color-index values of the pixels
// This is a bottom-up DIB, so the colors will be in horizontal bands, 64 rows high,
// in the order (bottom-up) of R, G, Bfor ( int iRow=0; iRow<256; ++iRow )
{
for ( int iCol=0; iCol<256; ++iCol )
{
switch ( (iRow/64)%4 )
{
case 0: *pBits = 0; break;
case 1: *pBits = 1; break;
case 2: *pBits = 2; break;
case 3: *pBits = 0; break;
}pBits++;
}
}// blt the DDB bitmap to the display device contextCBitmap bm;
bm.Attach( hBM );CDC memDC;
memDC.CreateCompatibleDC( pDC );
CBitmap* pOldBM = memDC.SelectObject( &bm );pDC->BitBlt( 0, 0, 256, 256, &memDC, 0, 0, SRCCOPY );memDC.SelectObject( pOldBM );}大家可以看到红色部分,我们在上面定义的调色板,然后调用CreateDIBSection返回一个HBitmap,我觉得在memDC中应该把返回的这个HBitmap中的调色板解析出来,再select到memDC中。这样其实就把它当成了一个DDB来操作了,而不是DIB. 但是这个函数返回的是DIB,而不是DDB。哪位大虾能解释一下。
解决方案 »
- cannot open file "vfw.lib"
- 请教个问题啊 使用CListCtrl EnsureVisible 显示可视区时 当大量数据再次插入时 出现刷屏 需怎么解决啊
- IOCP GetQueueCompletionStatus()返回0是,就是客户端断开了连接吗?
- 如何用打印机按要求打印指定的文件(熟悉打印的朋友进来,来者有分)
- 急求RTP,RTCP中文版资料
- 关于windows下原始socket接收tcp数据的问题
- [求助][求助]怎样在鼠标处显示文奔?
- 请教函数OnSetCursor()在什么时候响应(调用)
- 怎样在对话框中响应CHECK BOX BN_CLICK消息把某一编辑框属性改为READONLY?
- 如何判断一个进程是系统进程还是用户进程??????
- 属性表单问题
- 将console嵌入MFC的dialog中或者其他方法
biCompression = BI_RGB
所以不需要调色板。在你的这个例子里并不需要对SIBITMAPINFO.bmiColor赋值
在高发色数系统上,那确实是没必要的,因为转成DDB显示后,都不需要调色板了(因为系统发色数大于256).
至于很多示例都依然创建/实现调色板那是考虑上下兼容的问题,考虑一下那些依然工作在256色及以下的老系统吧,不创建/实现调色板将不能正确显示颜色呢.试试把系统设置为256色就知道了..
实际上现在很多的流行代码估计放到256色(或以下)系统都会死得很难看的,因为根本没有考虑这个问题.btw:bmiColor可不是调色板哦,那是bmp的色彩表,不要和系统的palette混为一谈..
首先,函数返回的DIB section,怎么转成DDB了,有点不明白。
其次:按照你的解释,如果在高发色数系统上,内存HDC提供的色数会满足DIB section的使用。如果在低于256色以下,需要创建色彩表,那么创建了色彩表后,调用CreateDIBSection函数,会自动把色彩表值赋值给内存HDC吗,还是需要手工解析后再赋给内存HDC.
我的理解是在创建DIBSection对象时,使用DIB的调色板去初始化设备DC的调色板。然后直接使用设备DC的调色板去处理DIBSection数据。
如果SIBITMAPINFO.bmiColor没有相关的调色板数据,就直接使用内存设备DC中的调色板,是这样理解吗?
很明显你的目前XP的系统一般是在32位的模式下运行,足够来显示你位图中的所有颜色,那么选择8位位图的调色盘到DC中完全是无效的,你可以使用GetDeviceCaps (hdc, RASTERCAPS)来查询一下系统需不需要使用调色盘,假如需要的话你才有必要把位图中的调色盘选入DC。