通过截屏得到了一幅HBITMAP
这个区域中只使用了4种颜色我生成了一个调色板如下:
PALETTEENTRY entries[]={{0,0,0,PC_RESERVED},{255,0,0,PC_RESERVED},{0,255,0,PC_RESERVED},{255,255,0,PC_RESERVED}};
LPLOGPALETTE pLogPalette = (LPLOGPALETTE)_alloca((DIM_OF_ARRAY(entries)-1)*sizeof(PALETTEENTRY)+sizeof(LOGPALETTE));
if(!pLogPalette)throw TEXT("Out of memory.");
pLogPalette->palVersion = 0x300;
pLogPalette->palNumEntries = DIM_OF_ARRAY(entries);
memcpy(pLogPalette->palPalEntry,entries,sizeof(entries));
m_palette.CreatePalette(pLogPalette);然后调用了DDBToDIB函数(这个函数是在网上找的,应该没有问题)。并传入m_Palette作参数,但为何产生出来的DIB的biBitCount还是0x20(即十进制32)?我也试过在截屏之前将调色板选入DC中,结果仍是一样的:
//构造作画的画纸
CDC *pDC = GetDC();
CDC memdc;memdc.CreateCompatibleDC(pDC);
CBitmap bitmap;bitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
CBitmap *pOldBitmap = (CBitmap*)memdc.SelectObject(&bitmap);
CPalette *pOldPalette = (CPalette*)memdc.SelectObject(&m_palette);
memdc.RealizePalette(); //画背景及文字
DrawPosterBackGroundImage(&memdc,m_pHBitmapBk[frameIndex],rect); //清理
memdc.SelectObject(pOldBitmap);
memdc.SelectObject(pOldPalette);
memdc.DeleteDC();
ReleaseDC(pDC);要怎么弄才能使产生的位图数据是每个像素一个字节,并且这个字节的值为其在我设置的调色板中的颜色表的编号呢?奉上150分,谢谢大虾指教。
这个区域中只使用了4种颜色我生成了一个调色板如下:
PALETTEENTRY entries[]={{0,0,0,PC_RESERVED},{255,0,0,PC_RESERVED},{0,255,0,PC_RESERVED},{255,255,0,PC_RESERVED}};
LPLOGPALETTE pLogPalette = (LPLOGPALETTE)_alloca((DIM_OF_ARRAY(entries)-1)*sizeof(PALETTEENTRY)+sizeof(LOGPALETTE));
if(!pLogPalette)throw TEXT("Out of memory.");
pLogPalette->palVersion = 0x300;
pLogPalette->palNumEntries = DIM_OF_ARRAY(entries);
memcpy(pLogPalette->palPalEntry,entries,sizeof(entries));
m_palette.CreatePalette(pLogPalette);然后调用了DDBToDIB函数(这个函数是在网上找的,应该没有问题)。并传入m_Palette作参数,但为何产生出来的DIB的biBitCount还是0x20(即十进制32)?我也试过在截屏之前将调色板选入DC中,结果仍是一样的:
//构造作画的画纸
CDC *pDC = GetDC();
CDC memdc;memdc.CreateCompatibleDC(pDC);
CBitmap bitmap;bitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
CBitmap *pOldBitmap = (CBitmap*)memdc.SelectObject(&bitmap);
CPalette *pOldPalette = (CPalette*)memdc.SelectObject(&m_palette);
memdc.RealizePalette(); //画背景及文字
DrawPosterBackGroundImage(&memdc,m_pHBitmapBk[frameIndex],rect); //清理
memdc.SelectObject(pOldBitmap);
memdc.SelectObject(pOldPalette);
memdc.DeleteDC();
ReleaseDC(pDC);要怎么弄才能使产生的位图数据是每个像素一个字节,并且这个字节的值为其在我设置的调色板中的颜色表的编号呢?奉上150分,谢谢大虾指教。
[code=C/C++]// stdafx.cpp : source file that includes just the standard includes
// PosterSpirit.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type informationHANDLE DDBToDIB(CBitmap &bitmap,DWORD dwCompression = BI_RGB,CPalette *pPal = NULL)
{
BITMAP bm;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
DWORD dwLen;
HANDLE handle;
HANDLE hDIB;
HDC hDC;
HPALETTE hPal;
ASSERT(bitmap.GetSafeHandle());
// The function has no arg for bitfields
if(dwCompression == BI_BITFIELDS)
return NULL;
// If a palette has not been supplied use defaul palette
hPal =(HPALETTE)pPal->GetSafeHandle();
if(hPal==NULL)
hPal =(HPALETTE)GetStockObject(DEFAULT_PALETTE);
// Get bitmap information
bitmap.GetObject(sizeof(bm),(LPSTR)&bm);
//>> 填充位图信息头 bitmapinfoheader
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel;
bi.biCompression = dwCompression;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
//<<
// Compute the size of the infoheader and the color table
int nColors = pPal->GetEntryCount();;
if(nColors > 256)nColors = 0;
dwLen = bi.biSize + nColors * sizeof(RGBQUAD);
// We need a device context to get the DIB from
hDC = GetDC(NULL);
hPal = SelectPalette(hDC,hPal,FALSE);
RealizePalette(hDC);
// Allocate enough memory to hold bitmapinfoheader and color table
hDIB = GlobalAlloc(GMEM_FIXED,dwLen);
if(!hDIB)
{
SelectPalette(hDC,hPal,FALSE);
ReleaseDC(NULL,hDC);
return NULL;
}
lpbi =(LPBITMAPINFOHEADER)hDIB;
*lpbi = bi;
// Call GetDIBits with a NULL lpBits param,so the device driver
// will calculate the biSizeImage field
GetDIBits(hDC,(HBITMAP)bitmap.GetSafeHandle(),0L,(DWORD)bi.biHeight,(LPBYTE)NULL,(LPBITMAPINFO)lpbi,DIB_RGB_COLORS);
bi = *lpbi;
// If the driver did not fill in the biSizeImage field,then compute it
// Each scan line of the image is aligned on a DWORD(32bit)boundary
if(bi.biSizeImage == 0)
{
bi.biSizeImage =((((bi.biWidth * bi.biBitCount)+ 31) & ~31) / 8) * bi.biHeight;
// If a compression scheme is used the result may infact be larger
// Increase the size to account for this.
if(dwCompression != BI_RGB)bi.biSizeImage =(bi.biSizeImage * 3) / 2;
}
// Realloc the buffer so that it can hold all the bits
dwLen += bi.biSizeImage;
if(handle = GlobalReAlloc(hDIB,dwLen,GMEM_MOVEABLE))
hDIB = handle;
else
{
GlobalFree(hDIB);
// Reselect the original palette
SelectPalette(hDC,hPal,FALSE);
ReleaseDC(NULL,hDC);
return NULL;
}
// Get the bitmap bits
lpbi =(LPBITMAPINFOHEADER)hDIB;
// FINALLY get the DIB
BOOL bGotBits = GetDIBits( hDC,(HBITMAP)bitmap.GetSafeHandle(),
0L, // Start scan line
(DWORD)bi.biHeight, // # of scan lines
(LPBYTE)lpbi // address for bitmap bits
+(bi.biSize + nColors * sizeof(RGBQUAD)),
(LPBITMAPINFO)lpbi, // address of bitmapinfo
DIB_RGB_COLORS); // color table
if(!bGotBits)
{
GlobalFree(hDIB);
SelectPalette(hDC,hPal,FALSE);
ReleaseDC(NULL,hDC);
return NULL;
}
SelectPalette(hDC,hPal,FALSE);
ReleaseDC(NULL,hDC);
return hDIB;
}
2. 把调色板选进设备句柄你的位图里的数值只要是0,1,2,3就可以了
请教这个BITMAPINFO结构要怎么样初始化呢?
如5楼所言确实我只需要数据里是0、1、2、3就可以了。
另外,将24位色的图通过上述方法取得256色的DIB后,是不是颜色表中没有的像素会转为相近的颜色?
我的最终目的是要转成4种颜色(黑红绿黄),用于双基色LED显示。
诚如5楼所言,只需要数据是0、1、2、3就可以了。
谢谢大家。
这种方式得到的调色板是函数内部自动生成的,调色板也会通过BITMAPINFO结构返回。