原文出处:http://blog.csdn.net/ThomasLiu83/archive/2005/08/01/443385.aspx

透明和不透明:

        透明象素是那些不会影响目标文件的象素,看不见的象素;不透明象素就是将会出现在目标文件上覆盖原来位置的点的象素。


白色和黑色:分别被假定为全1和全0的值


基本的操作:BitBlt涉及到从源文件到目标文件的块传递,另外也有单色和彩色位图之间的转换。

单色和彩色位图之间的转换:从单色位图到彩色位图,单色位图中是1的地方需要先转换为彩色位图的背景色,全0的地方需要转换为前景色,然后在进行块间操作;从彩色位图到单色位图,彩色位图中所有和背景色一致的地方设置为全1,即白色,其余部分为0,黑色,然后操作。


(原文:When using BitBlt() to convert a monochrome bitmap to a color bitmap, GDI transforms all white bits (1) to the background color of the destination device context (DC). GDI transforms all black bits (0) to the text (or foreground) color of the destination DC. When using BitBlt() to convert a color bitmap to a monochrome bitmap, GDI sets to white (1) all pixels that match the background color of the source DC. All other bits are set to black (0).)


光栅操作:

        BitBlt函数的最后一个参数指定了一个光栅操作(ROP),它明确定义了如何将源文件、目标文件和模式(由现在选出的刷子画笔定义)的位组合去形成一个目标文件。因为一个位图只是一个位值的集合,光栅操作(ROP)只是一个在位上操作的布尔等式。相应使用的设备,位图中的代表不同的事物。

        在多色设备上,每个象素由一个位集合代表,他们要么形成一个指向颜色的索引,要么直接代表一种颜色。
        在单色设备上,每个象素由一个位来代表,0表示黑色并且1代表白色。
对于所有的设备类型,光栅操作(ROP)只简单地在位展示上进行而不考虑他们的实际意义。

SRCCOPY

src

直接将源拷到目的地
SRCAND src and dest 将目标文件中对应于源文件黑色区域的部分变黑,将对应于白色区域的部分留着不动
SRCINVERT src XOR dest 将源插入到目标。二次使用时,将目标恢复到它原来的状态。在某种条件下可以代替SRCPAINT 操作
SRCPAINT src OR dest 将源文件中的非白色区域刷到目标文件中。源中的黑色区域不转换到目标中。

主要介绍的光栅操作:  SRCINVERT实现异或操作,两次异或操作相同于还原,例如1与1异或为0,0再与1异或结果还为1,回到之前的值。

使用举例: 

  1. /* 自绘制透明位图的函数                                                 */ 
  2.  
  3. BOOL DrawTransparentBmp(HDC hdcDest,  
  4.                         int nXOriginDest,  
  5.                         int nYOriginDest,  
  6.                         int nWidthDest,  
  7.                         int nHeightDest,  
  8.                         HDC hdcSrc,  
  9.                         int nXOriginSrc,  
  10.                         int nYOriginSrc,  
  11.                         int nWidthSrc,  
  12.                         int nHeightSrc,  
  13.                         UINT crTransparent)  
  14. {  
  15.     if (nWidthDest < 1)  
  16.     {  
  17.         return false;  
  18.     }  
  19.  
  20.     if (nWidthSrc < 1)  
  21.     {  
  22.         return false;  
  23.     }  
  24.  
  25.     if (nHeightDest < 1)  
  26.     {  
  27.         return false;  
  28.     }  
  29.  
  30.     if (nHeightSrc < 1)  
  31.     {  
  32.         return false;  
  33.     }  
  34.  
  35.     HDC hMaskDC,hImageDC;  
  36.     HBITMAP hMaskBitmap,hOldMaskBitmap;  
  37.     HBITMAP hImageBitmap,hOldImageBitmap;  
  38.  
  39.     //创建mask DC 和临时存源文件的 DC  
  40.     hMaskDC = CreateCompatibleDC(hdcDest);  
  41.     hImageDC = CreateCompatibleDC(hdcDest);  
  42.  
  43.     //创建mask 位图和p_w_picpath 兼容位图  
  44.     hMaskBitmap = CreateBitmap(nWidthSrc,nHeightSrc,1,1,NULL);   //单色位图  
  45.     hImageBitmap = CreateCompatibleBitmap(hdcDest,nWidthSrc,nHeightSrc);  //彩色位图  
  46.  
  47.     //将位图选进DC中  
  48.     hOldImageBitmap = (HBITMAP)SelectObject(hImageDC,hImageBitmap);  
  49.     hOldMaskBitmap = (HBITMAP)SelectObject(hMaskDC,hMaskBitmap);  
  50.  
  51.     //将src位图拷入临时的p_w_picpath DC中  
  52.     if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)  
  53.     {  
  54.         BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest,
  55.   hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);  
  56.     }  
  57.     else 
  58.     {  
  59.         StretchBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, 
  60. nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);  
  61.     }  
  62.  
  63.     //设置整个需要透明的颜色  
  64.     SetBkColor(hImageDC,crTransparent);  
  65.     //此步生成掩码位图(mask bitmap),注意整个位图中白为1,黑为0  
  66.     //整个mask 位图中透明色的地方是白色,其他为黑色  
  67.     BitBlt(hMaskDC, 0, 0, nWidthSrc, nHeightSrc, 
  68. hImageDC, nXOriginSrc, nYOriginSrc, SRCCOPY);  
  69.     SetBkColor(hdcDest, RGB(255, 255, 255));  
  70.     SetTextColor(hdcDest, RGB(0, 0, 0));  
  71.  
  72.     BitBlt(hdcDest, nXOriginDest, nYOriginDest, 
  73. nWidthSrc, nHeightDest, hImageDC, nXOriginSrc, nYOriginSrc, SRCINVERT);  
  74.     BitBlt(hdcDest, nXOriginDest, nYOriginDest, 
  75. nWidthSrc, nHeightDest, hMaskDC, 0, 0, SRCAND);  
  76.     BitBlt(hdcDest, nXOriginDest, nYOriginDest, 
  77. nWidthSrc, nHeightDest, hImageDC, nXOriginSrc, nYOriginSrc, SRCINVERT);  
  78.     return true;  

 

解说:

// Set up destination for monochrome blt (only needed for monochrome
// mask). These are the default values and may not need to be
// changed. They should also be restored.
SetBkColor(hdcDest, RGB(255, 255, 255)); // 1s --> 0xFFFFFF
SetTextColor(hdcDest, RGB(0, 0, 0)); // 0s --> 0x000000

// Do the real work.
BitBlt(hdcDest, x, y, dx, dy, hdcSrc, x0, y0, SRCINVERT);
BitBlt(hdcDest, x, y, dx, dy, hdcMask, 0, 0, SRCAND);
BitBlt(hdcDest, x, y, dx, dy, hdcSrc, x0, y0, SRCINVERT);
被屏蔽的块传递处理中的三步操作如下:
第一步(带SRCINVERT的位块传递)将源位图异或到目标文件。这看起来有点意思,但第二步异或有把目标文件恢复成原始状态的效果。
第二步(带SRCAND的位块传递)是一个屏蔽操作。当屏蔽与目标文件相与,所有的透明象素都不会改变目标文件的象素,而不透明象素则直接把目标文件变为黑。现在目标文件中有了一个源文件的不透明部分给勾勒出来的图象,而它自身在透明部分中的异或图象。
第三步(带SRCINVERT的位块传递)与源文件异或送到目标文件。透明象素被恢复成源状态(两步异或就能做到),不透明象素则季节从源文件上复制。