使PictureBox图片透明

PictureBox加载透明png图片后透明部分显示的是容器背景色,无法透明显示背景图,以下方法可以实现透明(缺点:有锯齿,无半透明效果)

原理:抠除alpha为0的像素点,重新计算控件region

        private unsafe static GraphicsPath SubGraphicsPath(System.Drawing.Image img)
        {
            if (img == null) return null;

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

            System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(img);

            int width = bitmap.Width;
            int height = bitmap.Height;
            BitmapData bmData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            byte* p = (byte*)bmData.Scan0;
            int offset = bmData.Stride - width * 4;

            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[3] > 0)     //如果 之前的点没有不透明 且 不透明   
                    {
                        start = X;                            //记录这个点  
                    }
                    else if (start > -1 && p[3] == 0)    //如果 之前的点是不透明 且 透明  
                    {
                        g.AddRectangle(new System.Drawing.Rectangle(start, Y, X - start, 1));    //添加之前的矩形到  
                        start = -1;
                    }

                    if (X == width - 1 && start > -1)        //如果 之前的点是不透明 且 是最后一个点  
                    {
                        g.AddRectangle(new System.Drawing.Rectangle(start, Y, X - start + 1, 1));      //添加之前的矩形到  
                        start = -1;
                    }
                    p += 4;                                   //下一个内存地址  
                }
                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(System.Windows.Forms.Control control, System.Drawing.Image img)
        {
            GraphicsPath g;
            g = SubGraphicsPath(img);
            if (g == null)
                return;
            control.Region = new System.Drawing.Region(g);
        }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值