HDC hRBkDc = GetDC(m_window);        //为了获取当前窗口的背景,也就是游戏背景
HDC hBkDc = CreateCompatibleDC(hDc);  //为了把当前窗口背景的内容联系到一个HBITMAP:
                                      //用hBkDc选入一个HBITMAP即bCurBk进来,然后hBkDc作为目的,
                                      //从hRBkDc BitBlt背景内容进来,bCurBk的内容就为当前背景
HBITMAP bCurBk = CreateCompatibleBitmap(hRBkDc, WINWIDTH, WINHEIGHT);//WINWIDTH为窗宽
HBITMAP hBkOldBmp =(HBITMAP)SelectObject(hBkDc,bCurBk);              //保存原HBITMAP,这是一般流程
BitBlt(hBkDc,0,0,WINWIDTH,WINHEIGHT,hRBkDc,0,0,SRCCOPY);             //从hRBkDc BitBlt背景内容到hBkDc//获取bCurBk的尺寸,主要是bmWidthBytes
BITMAP bmpBK;                         
GetObject(bCurBk,sizeof(BITMAP),&bmpBK);
pBmpBK = new unsigned char [bmpBK.bmHeight * bmpBK.bmWidthBytes];//从bCurBk内获取内容到pBmpBK,用于后面对背景数据的运算
BITMAPINFO   bminfo1 = {0};
bminfo1.bmiHeader.biSize = sizeof(bminfo1.bmiHeader);
GetDIBits(hDc,bCurBk,0,bmpBK.bmHeight,NULL,&bminfo1,DIB_RGB_COLORS);
GetDIBits(hDc,bCurBk,0,bmpBK.bmHeight,pBmpBK,&bminfo1,DIB_RGB_COLORS);//获取前景图片,就是游戏角色的图片
BITMAP bitmap;
GetObject((*ihb)->m_CurBmp,sizeof(BITMAP),&bitmap);   //(*ihb)->m_CurBmp为游戏角色图片的HBITMAP
hFinal = CreateCompatibleBitmap (hDc,bitmap.bmWidth,bitmap.bmHeight) ;  //为了不改动愿角色图片,故生成此HBITMAP
BITMAPINFO   bminfo = {0};
bminfo.bmiHeader.biSize = sizeof(bminfo.bmiHeader);

//获取游戏角色图片内容到pBmpMem
GetDIBits(hDc,(*ihb)->m_CurBmp,0,bitmap.bmHeight,NULL,&bminfo,DIB_RGB_COLORS);
pBmpMem = new unsigned char [bminfo.bmiHeader.biSizeImage];
int   lineScaned   =   GetDIBits(hDc,(*ihb)->m_CurBmp,0,bitmap.bmHeight,pBmpMem,&bminfo,DIB_RGB_COLORS);
DWORD dwL = GetLastError();int mx = 0,my = 0;
for (my = 0; my < bitmap.bmHeight; my++)
{
   for (mx = 0; mx < bitmap.bmWidthBytes/(bitmap.bmBitsPixel/8);mx++)
   {
       int iRGB = my * ((bitmap.bmWidth * 3 + 1)/2) * 2  + mx*3;       int iRGBBK = my * bmpBK.bmWidthBytes   + mx * 4;    //注意:这里是4图片比例才正常,为3则横向放大!!!

       //为了实验,现在先把部分背景作为角色图片
       pBmpMem[iRGB] = pBmpBK[iRGBBK];
       pBmpMem[iRGB+1] = pBmpBK[iRGBBK+1];
       pBmpMem[iRGB+2] = pBmpBK[iRGBBK+2];
     }
}//处理后,也就是把背景图片的一部分做为角色图片后,把角色图片内容关联到hFinal,然后进入一个HDC hDcObj准备显示
SetDIBits(hDc,hFinal,0,bitmap.bmHeight,pBmpMem,&bminfo,DIB_RGB_COLORS);
hOldBmp = (HBITMAP)SelectObject(hDcObj,hFinal); //GDI善后流程
SelectObject(hBkDc,hBkOldBmp);
DeleteObject(bCurBk);
DeleteDC(hBkDc);
ReleaseDC(m_window,hRBkDc);

//把hFinal显示出来
BitBlt(hDcBuffer,(*ihb)->m_lefttop.x - pMainRole->m_lefttop.x + WINWIDTH/2 - pMainRole->m_iWidth/2,
(*ihb)->m_lefttop.y - pMainRole->m_lefttop.y + WINHEIGHT/2 - pMainRole->m_iHeight/2,
(*ihb)->m_iWidth,(*ihb)->m_iHeight,hDcObj,
0,0,SRCCOPY);

解决方案 »

  1.   

    代码如上,感叹号处就是问题,从GetDIBits出来的图片数据,在pBmpMem里是3个字节存放RGB值,紧接着是下个相素的3个字节RGB值,而在pBmpBK里相邻两个相素虽然也是3个字节存放RGB值,但中间却有隔着一个不知道怎么回事的1字节.
      

  2.   

    GetDIBits 用到了 BITMAPINFO, 如果一个图片是 24位的应该 *3
    如果是32位的就应该 *4 , 具体的可以调试看 BITMAPINFO 里面的信息
      

  3.   

    建议你认真地看看BITMAPINFO结构体说明
      

  4.   

    在详细具体点说说吧,我查了查这个结构的一些中文资料和MSDN英文资料,没发现这些东西.
      

  5.   

    断下来了,从背景图片获取的BITMAPINFO的biBitCount为32,biCompression为3。而从角色图片获取的这两个值分别为24和0。
    搜到的资料是:
    /************************************/
    32
     位图最多有2^32种颜色。如果BITMAPINFOHEADER 的biCompression 成员是BI_RGB , bmiColors 为NULL。位图数组中的每个双字(DWORD)分别代表每个像素的蓝、绿、红色的相对强度。每个双字的高字节不使用。bmiColors 颜色表用来优化使用在基于调色板的设备上的颜色,而且必须包含BITMAPINFOHEADER的biClrUsed 成员指定的入口数量。如果BITMAPINFOHEADER 的biCompression 的值为BI_BITFIELDS,bmiColors 成员包含3个双字颜色掩码来分别指定组成每个像素的红、绿、蓝色。位图数组中的每个双字代表一个像素。
     biCompression:为压缩的bottom-up位图指定压缩类型,而top-down DIBs 不能被压缩。该成员值可能为下表中的一个:

     描述
     
    BI_RGB  
     未压缩的格式
     
    BI_BITFIELDS 
     用来说明位图没有被压缩并且颜色表由3个双字颜色掩码组成(3个双字颜色掩码来分别指定组成每个像素的红、绿、蓝值)。当使用16bpp和32bpp位图时该标志可用。该值在Windows CE 2.0 及其以后版本可用。
     /**************************************/
    但具体BI_BITFIELDS 时图片数据是怎么组织的,还是不明白。到底一个相素的RGB是一个DWORD怎么表示,后面说的3个双字颜色掩码又是怎么回事???
      

  6.   

    好吧,总之是有关BITMAPINFO的知识,貌似还比较复杂,本帖应该可以结帖了