感谢大家在
如何置换bitmap背景色?
如何将RGB颜色(24Bits)转换为16Bits的颜色?
中的解答。
现在想请大家就
Window系统下 8Bit(256色)/16bit(增强色)/真彩色(32bit) 下
对于同一位图
CBitmap::GetBitmapBits(dwCount,lpBits);中lpBits数据如何相应变化进行解疑,谢谢?

解决方案 »

  1.   

    比如我还是要改变背景色。只是想通过下面的方法进行改变:
    //CBitmap bmpList;通过CBitmap::Load方法载入图像资源
    DWORD dwCount;
    BYTE  * lpBits;
    dwCount = bmpInfo.bmWidthBytes * bmpInfo.bmHeight;
    lpBits = new BYTE[dwCount];
    bmpList.GetBitmapBits(dwCount,lpBits); 
    原位图是24*24像素,位图的第一个像素RGB(r,g,b)
    当真彩色(32bit)时,对应4个字节b,g,r,0
    当16bit(增强色)时,对应2个字节x,y 
    注: 0<=b,g,r,x,y <=255 很想知道x,y是怎样根据像素RGB(r,g,b)换算出来的?
      

  2.   

    ConvertToTrueColorImage(BITMAPINFOHEADER bitInfo,HBITMAP hBitmap)
    {
    HDC  hdc;  
    CDC dc;
        int iBits; 
    WORD wBitCount;   
    DWORD dwBmBitsSize, dwDIBSize, dwWritten;
    BITMAPFILEHEADER bmfHdr; 
    BITMAPINFOHEADER  bi; 
    LPBITMAPINFOHEADER lpbi;
    HANDLE hDib;  
    try
    {

    dc.CreateDC("DISPLAY", "DISPLAY", 0, 0);  
    hdc = dc.m_hDC;
    BITMAP BMP;
    wBitCount = 24;
    bi.biSize            = sizeof(BITMAPINFOHEADER);
    bi.biWidth           = abs(bitInfo.biWidth);
    bi.biHeight          = abs(bitInfo.biHeight);
    bi.biPlanes          = 1;
    bi.biBitCount         = wBitCount;
    bi.biCompression      = BI_RGB;
    bi.biSizeImage        = bitInfo.biSizeImage;
    bi.biXPelsPerMeter     = bitInfo.biXPelsPerMeter;
    bi.biYPelsPerMeter     = bitInfo.biYPelsPerMeter;
    bi.biClrUsed         = 0;
    bi.biClrImportant      = 0;
    dwBmBitsSize = ((bi.biWidth *wBitCount+31)/32)* 4*bi.biHeight ;
    hDib  = GlobalAlloc(GHND,dwBmBitsSize+sizeof(BITMAPINFOHEADER));
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
    *lpbi = bi; // CClientDC dc(this);

    GetDIBits(hdc, hBitmap, 0, (UINT) bi.biHeight,(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
    ,(BITMAPINFO *)lpbi, DIB_RGB_COLORS);

    bmfHdr.bfType = 0x4D42;  
    dwDIBSize    =  sizeof(BITMAPINFOHEADER)+ dwBmBitsSize;  
    bmfHdr.bfSize = dwDIBSize;
    bmfHdr.bfReserved1 = 0;
    bmfHdr.bfReserved2 = 0;
    bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER);
    if(m_Data!=NULL)
    delete []m_Data;
    m_Data = new unsigned char[dwBmBitsSize];
    unsigned char *data = (unsigned char *)lpbi;
    memcpy(m_Data,&data[sizeof(BITMAPINFOHEADER)],dwBmBitsSize);

    if(m_FileHeaderData!=NULL)
    delete []m_FileHeaderData;
    m_FileHeaderData = new unsigned char[sizeof(BITMAPFILEHEADER)];
    memcpy(m_FileHeaderData,&bmfHdr,sizeof(BITMAPFILEHEADER));
    if(m_InfoHeaderData!=NULL)
    delete []m_InfoHeaderData;
    m_InfoHeaderData = new unsigned char[sizeof(BITMAPINFOHEADER)];
    memcpy(m_InfoHeaderData,&lpbi,sizeof(BITMAPINFOHEADER)); m_Depth = 24;
    m_BMPWidth  = bi.biWidth ;
    m_BMPHeight = bi.biHeight;
    m_Channel  = m_Depth/8;
    m_BytesPerLine = dwBmBitsSize/m_BMPHeight;
    BITMAPINFO  m_bmi;
    ZeroMemory( &m_bmi, sizeof( BITMAPINFO ) );
    m_bmi.bmiHeader= *lpbi;
    HBITMAP hBit = CreateDIBitmap(hdc,lpbi,CBM_INIT,m_Data,&m_bmi,DIB_RGB_COLORS|DIB_PAL_COLORS);
    if(m_hBitmap!=NULL)
    DeleteObject(m_hBitmap);
    m_hBitmap = (HBITMAP)CopyImage(hBit,IMAGE_BITMAP,m_BMPWidth,m_BMPHeight,LR_CREATEDIBSECTION);
    GlobalUnlock(hDib);
    GlobalFree(hDib);
    DeleteObject(hBit);
    }
    catch(...)
    {
    return _UNEXPECTED_ERROR;
    }
    return _NO_ERR;
    }
    把其他色彩图像变成真彩色的代码,可以参考一下
      

  3.   

    to romanticist(桃花岛主--杭州):
    thanks!
      

  4.   

    8Bit(256色)/16bit(增强色)/真彩色(32bit) 下lpBits指向的内容为:
    8bit: 指向byte阵列,每一个byte对应一个pixel. 其值是该pixel的颜色的在位图所带的调色板的index。
    16bit: 指向WORD阵列,每个WORD对应一个pixel.  其值是该pixel的颜色(RGB)  但是 各分量的位分配不痛  通常有RGB: 555   565  655 等  其默认情况 视不同显卡不同而异。
    24bit: 指向3-byte阵列,每个三个byte对应一个pixel.  其值是该pixel的颜色(RGB) 
    32bit:指向DWORD阵列,每个DWORD对应一个pixel.  其值是该pixel的颜色(RGB) 还剩一个byte在GDI里面没什么用的,只要是在OpenGL DirectX做辅助位平面的,比如alpha 分量如果你用坐标算地址  注意bitmap的4字节对齐规则   16bit下的位分派情况可以用API得到
      

  5.   

    to e_Boris(编程就像写诗):)
    16bit下的位分派情况指的是什么?用什么API可以得到?
      

  6.   

    to e_Boris(编程就像写诗):):
    有没有什么办法可以通过程序获得本地机显卡所采用的对16bit的WORD阵列的填充方式?
      

  7.   

    to e_Boris(编程就像写诗):):
    有没有什么办法可以通过程序获得本地机显卡所采用的对16bit的WORD阵列的填充方式?
      

  8.   

    如果当前是16bit的 可以:CWindowDC dc(NULL);   //current screenPIXELFORMATDESCRIPTOR  pfd; 
    HDC  hdc; 
    int  iPixelFormat; 
     
    iPixelFormat = GetPixelFormat(dc);
     
    // obtain detailed information about 
    // the device context's first pixel format 
    DescribePixelFormat(hdc, iPixelFormat,sizeof(PIXELFORMATDESCRIPTOR), &pfd);
      

  9.   

    看pfd里面的这些东西:
     BYTE  cRedBits; 
      BYTE  cRedShift; 
      BYTE  cGreenBits; 
      BYTE  cGreenShift; 
      BYTE  cBlueBits; 
      BYTE  cBlueShift; 如果当前不是16bit  
    你一个一个枚举iPixelFormat可能的值 直到DescribePixelFormat出错  分别查看pfd里面的内容
      

  10.   

    ms-help://MS.VSCC/MS.MSDNVS/Services/workshop/browser/filter/overview/SupportedPixelFormats.htm#inet_8Bit_Pixel_Formats
    ---------------------------------------------------------------------------------
    32-Bit Pixel Formats
    DDPF_ARGB32 — Eight bits each of alpha, red, green, and blue. The bits are stored in that order, with the alpha stored in the higher-order bits and the blue in the lower-order bits. This is one of the two preferred pixel formats used by DirectX Transform.DDPF_PMARGB32 — Eight bits each of alpha, red, green, and blue. This is essentially the same format as DDPF_ARGB32, except that each color has been alpha-premultiplied. Using this format makes the compositing of images more efficient because this removes several mathematical operations in the compositing process. This is the second of the two preferred pixel formats used by DirectX Transform. DDPF_RGB32 — Eight bits each of red, green, and blue. Alpha is undefined.DDPF_RGB32_CK — The same format as DDPF_RGB32, with one color treated as transparent.24-Bit Pixel Formats
    DDPF_RGB24 — Eight bits each of red, green, and blue. This format is more compact in memory than the 32-bit formats; however, access is slow because the samples are not aligned on 32-bit boundaries in memory.DDPF_RGB24_CK — The same format as DDPF_RGB24, with one color treated as transparent.16-Bit Pixel Formats
    DDPF_ARGB4444 — Four bits each of alpha, red, green, and blue. You should note that Graphics Device Interface (GDI) does not display this format properly on Microsoft Windows&reg; 95 or Windows 98.DDPF_RGB565 — This format uses 5 bits for red, 6 bits for green, and 5 bits for blue. The higher-order bits are used for red, while the lower order bits are used for blue.DDPF_RGB555 — Five bits each for red, green, and blue. The high-order bit is undefined.DDPF_RGB565_CK — The same format as DDPF_RGB565, with one color treated as transparent.DDPF_RGB555_CK — The same format as DDPF_RGB555, with one color treated as transparent.8-Bit Pixel Formats
    DDPF_RGB8 — This format uses an 8-bit number to index into a predefined palette of 256 colors. The default palette is the Windows halftone palette. DDPF_RGB8_CK — This is the same format as DDPF_RGB8, with one of the indices treated as transparent.
      

  11.   

    大家来得不晚!多谢关照:)
    HDC  hdc = GetDC(GetDesktopWindow());
    PIXELFORMATDESCRIPTOR  pfd; 
    int  iPixelFormat = 1;
     
    // obtain detailed information about 
    // the device context's first pixel format 
    DescribePixelFormat(hdc, iPixelFormat,sizeof(PIXELFORMATDESCRIPTOR), &pfd);
                                                     //16 bits     //32bits    //8Bits
    BYTE bPixelType =  pfd.iPixelType;           //0           //0         //0
    BYTE bColorBits  = pfd.cColorBits;           //16          //32        //8
    BYTE bRedBits    = pfd.cRedBits;             //5           //8         //3
    BYTE bRedShift   = pfd.cRedShift;            //11          //16        //0
    BYTE bGreenBits  = pfd.cGreenBits;           //6           //8         //3
    BYTE bGreenShift = pfd.cGreenShift;          //5           //8         //3
    BYTE bBlueBits   = pfd.cBlueBits;            //5           //8         //2
    BYTE bBlueShift  = pfd.cBlueShift;           //0           //0         //6
    BYTE bAlphaBits  = pfd.cAlphaBits;           //0           //8         //0
    BYTE bAlphaShift = pfd.cAlphaShift;          //0           //24        //0 BYTE bAccumBits      = pfd.cAccumBits;       //64          //64        //32
    BYTE bAccumRedBits   = pfd.cAccumRedBits;    //16          //16        //11
    BYTE bAccumGreenBits = pfd.cAccumGreenBits;  //16          //16        //11
    BYTE bAccumBlueBits  = pfd.cAccumBlueBits;   //16          //16        //10
    BYTE bAccumAlphaBits = pfd.cAccumAlphaBits;  //16          //16        //0
    BYTE bDepthBits   = pfd.cDepthBits;          //16          //16        //32
    BYTE bStencilBits = pfd.cStencilBits;        //0           //0         //8
    BYTE bAuxBuffers  = pfd.cAuxBuffers;         //0           //0         //0
    BYTE biLayerType  = pfd.iLayerType;          //0           //0         //0
    BYTE bReserved    = pfd.bReserved;           //0           //0         //0 WORD  nwSize     = pfd.nSize;                //40          //40        //40
    WORD  nwVersion  = pfd.nVersion;             //1           //1         //1
    DWORD ndwFlag    = pfd.dwFlags;              //52          //52        //252
    DWORD ndwLMask   = pfd.dwLayerMask;          //0           //0         //0
    DWORD ndwVMask   = pfd.dwVisibleMask;        //0           //0         //0
    DWORD ndwDMask   = pfd.dwDamageMask;         //0           //0         //0
      

  12.   

    像这样我得到了三种情况下的字节分配。按照e_Boris所言,8bit情况
    是其值是该pixel的颜色的在位图所带的调色板的index。
    16bits的情况我也已经清楚,但是现在的问题是如何将一个RGB的颜色值对应到8Bits下调色板上的index,又如何将RGB的一个颜色值对应成一个16bits的颜色值?c0der 兄曾在我的另一贴http://expert.csdn.net/Expert/topic/2085/2085688.xml?temp=.4903986指出了转换关系:
    //转换关系24-〉16
    5BitRed=8BitRed>>3;       //除以8
    6BitGreen=8BitGreen>>2;  //除以4
    5BitBlue=8BitBlue>>3;    //除以8
    Color=5BitBlue+(6BitGreen<<5)+(5BitRed<<11)  //颜色值
    但是我从CBitmap::GetBitmapBit获得的数据好像与转换后的数据不吻合。请c0der 兄和知情的兄弟们发表看法],谢谢
      

  13.   

    用GetDIBits得到的是否跟CBitmap::GetBitmapBit得到的一致?
      

  14.   

    我到现在才发现foxmail(萧遥) 是版主呀。
      

  15.   

    斑竹啊,你不能只笑啊:)
    to c0der():
    我通过上面的代码已经确定为565格式,想想时不是在转换的时候除了问题呢?
      

  16.   

    呵呵
    最近在忙着做新主页阿-> http://www.LoveSnow.com
    所以
    而且现在一般有人回答的帖子我不回答
    专门挑没人回答的帖子
    结果发现:很难,不会回答:P
      

  17.   

    to foxmail(萧遥) :
    斑竹啊,你是不是在准备讨好老婆的礼物啊,主页怎么这么"性感"?
      

  18.   

    to foxmail(萧遥) :
    不是啊,左边的旋转菜单很好找的啊,就是看到右边的图片有点晕!
      

  19.   

    to  foxmail(萧遥)  :  
    晕是因为脂粉气太重!
      

  20.   

    to farfh(慕容长风)
    长风兄,你说是不是?:)
      

  21.   

    借问一句:为什么要得到DDB的图像数据必须复制出来?有没有方法不用GetBitmapBits(),而能够直接得到DDB图像数据的地址然后直接做操作的?
    因为GetBitmapBits()太耗时了,800*600*32bit的图像,在我的机器上需要300ms!!