C# Winform控件贴透明png图片遇到的问题

转自:http://blog.csdn.net/gxtdjh/article/details/6215766   

用C# winform开发界面时会遇到很多小问题,首先贴透明的png图片后,图片无法透明,这点可以通过属性设置:外观/BackColor (Web TransParent)可以解决。

      但当用多个控件时,如PictureBox,控件都贴png透明图片后,两个PictureBox有重叠的地方,希望重叠的地方能透明,就是透视下面的控件部分,结果测试后发现两控件重叠透明的地方对整个框架的背景透明,但对下面控件无法透明,最后在网上找了一段代码,解决了这个问题。

对每个控件使用:ControlTrans(pic,pic.Image);然后层叠之后就可以透明了。


          /// <summary>
         /// 根据图片计算GraphicsPath路径
          /// </summary>
        /// <param name="img">gif或者png图片</param>
        /// <returns>图片不透明区域路径</returns>
        /// 用这个代码的时候需要选择项目属性->生成->勾选"允许不安全代码"
        /// 因为这里用到了指针,C#用指针式不安全的,具体可查看msdn
        private unsafe static GraphicsPath subGraphicsPath(Image img)
        {
            if (img == null) return null;

            // 建立GraphicsPath, 给我们的位图路径计算使用 
            GraphicsPath g = new GraphicsPath(FillMode.Alternate);

            Bitmap bitmap = new Bitmap(img);

            int width = bitmap.Width;
            int height = bitmap.Height;
            BitmapData bmData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            byte* p = (byte*)bmData.Scan0;
            int offset = bmData.Stride - width * 3;
            int p0, p1, p2;         // 记录左上角0,0座标的颜色值
            p0 = p[0];
            p1 = p[1];
            p2 = p[2];

            int start = -1;
            // 行座标 ( Y col ) 
            for (int Y = 0; Y < height; Y++)
            {
                // 列座标 ( X row ) 
                for (int X = 0; X < width; X++)
                {
                    if (start == -1 && (p[0] != p0 || p[1] != p1 || p[2] != p2))     //如果 之前的点没有不透明 且 不透明 
                    {
                        start = X;                            //记录这个点
                    }
                    else if (start > -1 && (p[0] == p0 && p[1] == p1 && p[2] == p2))      //如果 之前的点是不透明 且 透明
                    {
                        g.AddRectangle(new Rectangle(start, Y, X - start, 1));    //添加之前的矩形到
                        start = -1;
                    }

                    if (X == width - 1 && start > -1)        //如果 之前的点是不透明 且 是最后一个点
                    {
                        g.AddRectangle(new Rectangle(start, Y, X - start + 1, 1));      //添加之前的矩形到
                        start = -1;
                    }
                    //if (p[0] != p0 || p[1] != p1 || p[2] != p2)
                    //    g.AddRectangle(new Rectangle(X, Y, 1, 1));
                    p += 3;                                   //下一个内存地址
                }
                p += offset;
            }
            bitmap.UnlockBits(bmData);
            bitmap.Dispose();
            // 返回计算出来的不透明图片路径 
            return g;
        }

        /// <summary>
        /// 调用此函数后使图片透明
        /// </summary>
        /// <param name="control">需要处理的控件</param>
        /// <param name="img">控件的背景或图片,如PictureBox.Image
        ///   或PictureBox.BackgroundImage</param>
        public static void ControlTrans(Control control,Image img)
        {
            GraphicsPath        g;
            g                   = subGraphicsPath(img);
            if (g == null)
                return;
            control.Region        = new Region(g);
        }
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值