通过截屏得到了一幅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分,谢谢大虾指教。

解决方案 »

  1.   

    DDBToDIB,这个函数你确定可以转出带调色板的8位BITMAP出来?
      

  2.   

    不确定。对于调色板我一窍不通。
    [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; 
      

  3.   

    没听说有四个选项的调色板,单字节的一般都有256个颜色项,即使你的图像只有4个颜色,它只代表4个索引,但是调色板还是有256个项的。1. 首先创建一个256个PALETTEENTRY的调色板,把前四项设成你的那四种颜色
    2. 把调色板选进设备句柄你的位图里的数值只要是0,1,2,3就可以了
      

  4.   

    你是要得到一个256色DIB吗?只要先根据自己的需要初始化好一个BITMAPINFO结构,然后调用GetDIBits函数就可以了。
      

  5.   


    请教这个BITMAPINFO结构要怎么样初始化呢?
    如5楼所言确实我只需要数据里是0、1、2、3就可以了。
      

  6.   

    请教这个BITMAPINFO结构要怎么样初始化呢? 
    另外,将24位色的图通过上述方法取得256色的DIB后,是不是颜色表中没有的像素会转为相近的颜色?
    我的最终目的是要转成4种颜色(黑红绿黄),用于双基色LED显示。
    诚如5楼所言,只需要数据是0、1、2、3就可以了。
    谢谢大家。
      

  7.   

    BITMAPINFO需要初始化size、bitcount、width、height、planes,其余填0即可,函数调用成功后会填充整个结构。
    这种方式得到的调色板是函数内部自动生成的,调色板也会通过BITMAPINFO结构返回。