本文转自:http://www.cnblogs.com/haiq/articles/1751777.html
Winform窗体通常都是矩形的,而本人在需要将一幅图片作为窗体背景,并且窗体边框呈现为图片外轮廓的不规则边缘时,却发现Framework并没有提供直接的实现。经过一通百度、Google和查阅 MSDN 后,发现实现的途径主要有以下几种:
这三种方法各有优劣:
对于第3种方法,网上大多数的文章都只是介绍了实现的原理和一些简单的 Demo 代码。直接照做可能会遇到以下的一些问题而影响显示效果:
解决这两个问题很简单,是要注意一些操作的细节。先看实现代码:
不规则窗体的实现
1 //从指定的位图中获取透明度大于 10 的区域;
2 Bitmap img = (Bitmap)pictbox.Image;
3 GraphicsPath grapth = BitmapUtil.GetNoneTransparentRegion(img, 10);
4 this.Region = new Region(grapth);
5
6 //要显示的图片设置为窗体背景;
7 this.BackgroundImage = pictbox.Image;
8 this.BackgroundImageLayout = ImageLayout.Zoom;
9
10 //在修改窗体尺寸之前设置窗体为无边框样式;
11 this.FormBorderStyle = FormBorderStyle.None;
12 this.Width = pictbox.Image.Width;
13 this.Height = pictbox.Image.Height;
BitmapUtil.GetNoneTransparentRegion 方法的实现如下:
读取位图的非透明区域
1 /// <summary>
2 /// 返回指定图片中的非透明区域;
3 /// </summary>
4 /// <param name="img">位图</param>
5 /// <param name="alpha">alpha 小于等于该值的为透明</param>
6 /// <returns></returns>
7 public static GraphicsPath GetNoneTransparentRegion(Bitmap img, byte alpha)
8 {
9 int height = img.Height;
10 int width = img.Width;
11
12 int xStart, xEnd;
13 GraphicsPath grpPath = new GraphicsPath();
14 for (int y = 0; y < height; y++)
15 {
16 //逐行扫描;
17 for (int x = 0; x < width; x++)
18 {
19 //略过连续透明的部分;
20 while (x < width && img.GetPixel(x, y).A <= alpha)
21 {
22 x++;
23 }
24 //不透明部分;
25 xStart = x;
26 while (x < width && img.GetPixel(x, y).A > alpha)
27 {
28 x++;
29 }
30 xEnd = x;
31 if (img.GetPixel(x - 1, y).A > alpha)
32 {
33 grpPath.AddRectangle(new Rectangle(xStart, y, xEnd - xStart, 1));
34 }
35 }
36 }
37 return grpPath;
38 }
以上的代码中,解决边框与背景出现错误的办法是“在修改窗体尺寸之前设置窗体为无边框样式”,因为,窗体的长宽是包含在窗体标题栏的尺寸的,而背景显示图片的工作区是除去窗体标题栏的。
解决在设计时“界面控件在背景图片上的布局问题”可以也很简单,通过一些操作技巧就可以达到,具体如下: