main
1using System.Drawing;
2using System.Drawing.Drawing2D;
3using System.Windows.Forms;
4
5namespace MoMoney.Presentation.Winforms.Helpers
6{
7 public static class BitmapRegion
8 {
9 /// <summary>
10 /// create and apply the region on the supplied control
11 /// </summary>
12 /// <param name="control">The Control object to apply the region to</param>
13 /// <param name="bitmap">The Bitmap object to create the region from</param>
14 public static void CreateControlRegion(Control control, Bitmap bitmap)
15 {
16 // Return if control and bitmap are null
17 if (control == null || bitmap == null)
18 return;
19
20 // Set our control's size to be the same as the bitmap + 6 pixels so that the borders don't affect it.
21 control.Width = bitmap.Width;
22 control.Height = bitmap.Height;
23
24 // Check if we are dealing with Form here
25 if (control is Form)
26 {
27 // Cast to a Form object
28 var form = (Form) control;
29
30 // Set our form's size to be a little larger that the bitmap just
31 // in case the form's border style is not set to none in the first place
32 form.Width += 15;
33 form.Height += 35;
34
35 // No border
36 form.FormBorderStyle = FormBorderStyle.None;
37
38 // Set bitmap as the background image
39 form.BackgroundImage = bitmap;
40
41 // Calculate the graphics path based on the bitmap supplied
42 var graphicsPath = CalculateControlGraphicsPath(bitmap);
43
44 // Apply new region
45 form.Region = new Region(graphicsPath);
46 }
47
48 // Check if we are dealing with Button here
49 else if (control is Button)
50 {
51 // Cast to a button object
52 var button = (Button) control;
53
54 // Do not show button text
55 button.Text = "";
56
57 // Change cursor to hand when over button
58 button.Cursor = Cursors.Hand;
59
60 // Set background image of button
61 button.BackgroundImage = bitmap;
62
63 // Calculate the graphics path based on the bitmap supplied
64 var graphicsPath = CalculateControlGraphicsPath(bitmap);
65
66 // Apply new region
67 button.Region = new Region(graphicsPath);
68 }
69 }
70
71 /// <summary>
72 /// Calculate the graphics path that representing the figure in the bitmap
73 /// excluding the transparent color which is the top left pixel.
74 /// </summary>
75 /// <param name="bitmap">The Bitmap object to calculate our graphics path from</param>
76 /// <returns>Calculated graphics path</returns>
77 static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap)
78 {
79 // create GraphicsPath for our bitmap calculation
80 var graphicsPath = new GraphicsPath();
81
82 // Use the top left pixel as our transparent color
83 var colorTransparent = bitmap.GetPixel(0, 0);
84
85 // This is to store the column value where an opaque pixel is first found.
86 // This value will determine where we start scanning for trailing opaque pixels.
87 var colOpaquePixel = 0;
88
89 // Go through all rows (Y axis)
90 for (var row = 0; row < bitmap.Height; row ++)
91 {
92 // Reset value
93 colOpaquePixel = 0;
94
95 // Go through all columns (X axis)
96 for (var col = 0; col < bitmap.Width; col ++)
97 {
98 // If this is an opaque pixel, mark it and search for anymore trailing behind
99 if (bitmap.GetPixel(col, row) != colorTransparent)
100 {
101 // Opaque pixel found, mark current position
102 colOpaquePixel = col;
103
104 // create another variable to set the current pixel position
105 var colNext = col;
106
107 // Starting from current found opaque pixel, search for anymore opaque pixels
108 // trailing behind, until a transparent pixel is found or minimum width is reached
109 for (colNext = colOpaquePixel; colNext < bitmap.Width; colNext ++)
110 if (bitmap.GetPixel(colNext, row) == colorTransparent)
111 break;
112
113 // Form a rectangle for line of opaque pixels found and add it to our graphics path
114 graphicsPath.AddRectangle(new Rectangle(colOpaquePixel, row, colNext - colOpaquePixel, 1));
115
116 // No need to scan the line of opaque pixels just found
117 col = colNext;
118 }
119 }
120 }
121 // Return calculated graphics path
122 return graphicsPath;
123 }
124 }
125}