当前位置:编程学习 > C#/ASP.NET >>

C#下调用GDI的遮罩功能得不到预期效果如何解决

引用API:
        [DllImport("gdi32.dll   ")]
        private static extern bool BitBlt(
        IntPtr hdcDest,   //   handle   to   destination   DC    
        int nXDest,   //   x-coord   of   destination   upper-left   corner    
        int nYDest,   //   y-coord   of   destination   upper-left   corner    
        int nWidth,   //   width   of   destination   rectangle    
        int nHeight,   //   height   of   destination   rectangle    
        IntPtr hdcSrc,   //   handle   to   source   DC    
        int nXSrc,   //   x-coordinate   of   source   upper-left   corner    
        int nYSrc,   //   y-coordinate   of   source   upper-left   corner    
        uint dwRop   //   raster   operation   code    
        );
        /* Ternary raster operations */
        const uint SRCCOPY = 0x00CC0020; /* dest = source */
        const uint SRCPAINT = 0x00EE0086; /* dest = source OR dest */
        const uint SRCAND = 0x008800C6; /* dest = source AND dest */
        const uint SRCINVERT = 0x00660046; /* dest = source XOR dest */
        const uint SRCERASE = 0x00440328; /* dest = source AND (NOT dest ) */
        const uint NOTSRCCOPY = 0x00330008; /* dest = (NOT source) */
        const uint NOTSRCERASE = 0x001100A6; /* dest = (NOT src) AND (NOT dest) */
        const uint MERGECOPY = 0x00C000CA; /* dest = (source AND pattern) */
        const uint MERGEPAINT = 0x00BB0226; /* dest = (NOT source) OR dest */
        const uint PATCOPY = 0x00F00021; /* dest = pattern */
        const uint PATPAINT = 0x00FB0A09; /* dest = DPSnoo */
        const uint PATINVERT = 0x005A0049; /* dest = pattern XOR dest */
        const uint DSTINVERT = 0x00550009; /* dest = (NOT dest) */
        const uint BLACKNESS = 0x00000042; /* dest = BLACK */
        const uint WHITENESS = 0x00FF0062; /* dest = WHITE */

        [DllImport("gdi32.dll")]
        static public extern IntPtr CreateCompatibleDC(IntPtr hDC);
        [DllImport("user32.dll", EntryPoint = "GetDC")]
        public static extern IntPtr GetDC(IntPtr hWnd);
        [DllImport("gdi32.dll")]
        public static extern int SetROP2(int h, int op);
        [DllImport("gdi32.dll")]
        static public extern bool DeleteObject(IntPtr hObject);
        [DllImport("gdi32.dll")]
        static public extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
        [DllImport("gdi32.dll")]
        static public extern IntPtr DeleteDC(IntPtr hDC);

功能实现:
            Bitmap BmpB = new Bitmap("am.png");//am为遮罩图
            Bitmap BmpA = new Bitmap("a.png");//a为要实现透明的图

            Bitmap BmPBack = new Bitmap("b.png");//b是背景图,本帖附件给的是相关的图片

            Graphics g = pictureBox1.CreateGraphics();
            System.IntPtr hdc = g.GetHdc();

            System.IntPtr BmPBackDC = CreateCompatibleDC(hdc);
            System.IntPtr BmpADC = CreateCompatibleDC(hdc);
            System.IntPtr BmpBDC = CreateCompatibleDC(hdc);

            System.IntPtr Oldback = SelectObject(BmPBackDC, BmPBack.GetHbitmap());
            System.IntPtr OldA = SelectObject(BmpADC, BmpA.GetHbitmap());
            System.IntPtr OldB = SelectObject(BmpBDC, BmpB.GetHbitmap());

            BitBlt(hdc, 0, 0, BmpA.Width, BmpA.Height, BmPBackDC, 0, 0, SRCCOPY);
            BitBlt(hdc, 0, 0, BmpA.Width, BmpA.Height, BmpBDC, 0, 0, SRCAND);
            BitBlt(hdc, 0, 0, BmpA.Width, BmpA.Height, BmpADC, 0, 0, SRCPAINT);

            SelectObject(BmpBDC,OldB);
            SelectObject(BmpADC,OldA);
            SelectObject(BmPBackDC,Oldback);

            g.ReleaseHdc();
            DeleteDC(BmpADC);
            DeleteDC(BmpBDC);
            DeleteDC(BmPBackDC);
如题,个人写的这段代码不能实现利用遮罩的方式实现BMP图像透明效果,这段代码是仿照C++改的,C++代码如下:
void CDemoDlg::OnPaint() 

CPaintDC dc(this); 
CBitmap BmPBack,BmpA,BmpB,*pOldBack,*pOldA,*pOldB; 

BmpBack.LoadBitmap(IDB_BACKGROUND); // 载入背景图 
BmpA.LoadBitmap(IDB_BITMAPA); //载入图A 
BmpB.LoadBitmap(IDB_BITMAPB); //载入图B 

CDC dcBack,dcA,dcB; //声明三个内存DC用于画图 
dcBack.CreateCompatibleDC(&dc); 
dcA.CreateCompatibleDC(&dc); 
dcB.CreateCompatibleDC(&dc); //把这三个内存DC创建成和PaintDC兼容的DC 

pOldBack=dcBack.SelectObject(&BmpBack); 
pOldA=dcA.SelectObject(&BmpA); 
pOldB=dcB.SelectObject(&BmpB); //把三个位图选入相应的DC 

dc.BitBlt(0,0,100,100,&dcBack,0,0,SRCCOPY); //画背景 
dc.BitBlt(0,0,48,48,&dcB,0,0,SRCAND); //用与的方式画遮罩图B 
dc.BitBlt(0,0,48,48,&dcA,0,0,SRCPAINT); //用或的方式画遮图A 
个人还曾参考了这个地址上的文章,可是看了半天按照那个改还是不能实现预期功能:http://hi.baidu.com/char_string/blog/item/fa2a7b8b22cb047a9e2fb42b.html
求高手帮忙指正下问题所在 --------------------编程问答-------------------- 不要用那么复杂的 gdi+ 就可实现 不要总盯到一棵树  --------------------编程问答-------------------- 楼上,这个功能用GDI+是实现不了了,只有GDI能实现对位图的位操作。。。 --------------------编程问答-------------------- 用互操作,不如直接用C++ --------------------编程问答-------------------- 不知道楼主想要的透明效果是什么样子。
是不是跟你现在提供的图有关,尤其是背景图,
楼主可以对下面这三句进行调试,看看执行每一句是否是需要的效果(先注释掉第二、三句,然后恢复第二句,最后恢复第三句)。

dc.BitBlt(0,0,100,100,&dcBack,0,0,SRCCOPY); //画背景 
dc.BitBlt(0,0,48,48,&dcB,0,0,SRCAND); //用与的方式画遮罩图B 
dc.BitBlt(0,0,48,48,&dcA,0,0,SRCPAINT); //用或的方式画遮图A 
--------------------编程问答-------------------- 帮顶 --------------------编程问答-------------------- up --------------------编程问答-------------------- 学习一下,等待高手的解决方案 --------------------编程问答--------------------
引用 4 楼 slimfeng 的回复:
不知道楼主想要的透明效果是什么样子。 
是不是跟你现在提供的图有关,尤其是背景图, 
楼主可以对下面这三句进行调试,看看执行每一句是否是需要的效果(先注释掉第二、三句,然后恢复第二句,最后恢复第三句)。 

C# code
dc.BitBlt(0,0,100,100,&dcBack,0,0,SRCCOPY); //画背景 
dc.BitBlt(0,0,48,48,&dcB,0,0,SRCAND); //用与的方式画遮罩图B 
dc.BitBlt(0,0,48,48,&dcA,0,0,SRCPAINT); //用或的方式画遮图A 
这个是C++代码不是C#代码。。。。。。。 --------------------编程问答-------------------- 还是没人能帮忙解决么?
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,