C# Winform控件贴透明png图片遇到的问题
用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);
- }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?