利用 GraphicsPath 掃描位圖每一列像素,將不透明像素區間加入路徑,最後指派給按鈕的 Region 屬性,即可實現非矩形按鈕。
using System.Drawing.Drawing2D;
private void button3_Paint(object sender, PaintEventArgs e)
{
this.button3.Cursor = Cursors.Hand;
Bitmap bmp = (Bitmap)this.button3.Image;
GraphicsPath path = CalculateControlGraphicsPath(bmp);
this.button3.Region = new Region(path);
}
private static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap)
{
var path = new GraphicsPath();
Color transparentColor = bitmap.GetPixel(0, 0); // 假設左上角為透明色
for (int y = 0; y < bitmap.Height; y++)
{
int xStart = -1;
for (int x = 0; x < bitmap.Width; x++)
{
bool isOpaque = bitmap.GetPixel(x, y) != transparentColor;
if (isOpaque && xStart == -1)
xStart = x; // 開始不透明區間
else if (!isOpaque && xStart != -1)
{
// 結束不透明區間,加入矩形
path.AddRectangle(new Rectangle(xStart, y, x - xStart, 1));
xStart = -1;
}
}
// 處理行尾不透明區間
if (xStart != -1)
path.AddRectangle(new Rectangle(xStart, y, bitmap.Width - xStart, 1));
}
return path;
}
#FF00FF)的 PNG/BMP 圖片。Image 屬性,並設定 BackgroundImageLayout = None。Paint 事件中呼叫上述邏輯,或於 Load 事件一次性設定 Region。GetPixel 效能較差,大量像素處理建議使用 Bitmap.LockBits 直接存取記憶體。Region,避免重複計算。Control.Region 搭配 GraphicsPath 建構函式簡化程式碼。