WinForms 裁減繪圖區域

在 WinForms 中可以使用 Graphics 繪製圖形,不過 Graphics 的繪製區域會和父層有關,通常是 Forms 或是 按鈕等一個控制項的大小,基本上都是矩形。
如果我想要改變繪圖區域的形狀可以怎麼做?例如繪製大頭貼,將圖片繪製到畫布上,但是不是正方形而是只有一個圓圈的圖案:

複習一下基本的繪圖,將圖片畫到畫布上:
    
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        
        this.Paint += (sender, e) =>
        {
            var imagePath = @"C:\Users\ruyut\ruyut.png";
            if (!File.Exists(imagePath)) return;
            var image = Image.FromFile(imagePath);
            var graphics = e.Graphics;

			// 繪製圖片
            graphics.DrawImage(image, 10, 10, 100, 100);
        };
    }
}
    


但是這樣圖片是方形的耶,該怎麼讓他只有圓形區域呢?

使用 SetClip 裁減 graphics 區域

在 Graphics 中有許多圖形可以使用,使用各種圖形透過 SetClip 裁切掉指定區域以外的地方即可:
    
this.Paint += (sender, e) =>
{
    var imagePath = @"C:\Users\ruyut\ruyut.png";
    if (!File.Exists(imagePath)) return;
    var image = Image.FromFile(imagePath);
    var graphics = e.Graphics;

    // 裁減圓形區域
    var path = new GraphicsPath();
    path.AddEllipse(10, 10, 100, 100);
    graphics.SetClip(path);

    graphics.DrawImage(image, 10, 10, 100, 100);
};

    

恢復被裁減區域

除了圖案以外還有其他內容要繪製,這時候使用 ResetClip 直接重設繪圖區域,恢復被裁減前的樣子即可:
    
this.Paint += (sender, e) =>
{
    var imagePath = @"C:\Users\ruyut\ruyut.png";
    if (!File.Exists(imagePath)) return;
    var image = Image.FromFile(imagePath);
    var graphics = e.Graphics;

    // 裁減圓形區域
    var path = new GraphicsPath();
    path.AddEllipse(10, 10, 100, 100);
    graphics.SetClip(path);

    graphics.DrawImage(image, 10, 10, 100, 100);
    
    // 重設裁減區域
    graphics.ResetClip();
    
    // 繪製圓形外框
    using Pen pen = new Pen(Color.Green, 3);
    graphics.DrawEllipse(pen, 10, 10, 100, 100);
};
    

順便附上封面的範例:
(網頁底部有廣告可以免費觀看,請關閉廣告封鎖工具,感謝您的支持~)
    

var imagePath = @"C:\Users\ruyut\ruyut.png";

if (!File.Exists(imagePath)) return;
var image = Image.FromFile(imagePath);
var graphics = e.Graphics;


// 裁減,使其只顯示圓形區域
var path = new GraphicsPath();
path.AddEllipse(10, 10, 100, 100);
graphics.SetClip(path);

// 繪製圖形
graphics.DrawImage(image, 10, 10, 100, 100);

// 重設裁減區域
graphics.ResetClip();

// 繪製圓形外框
using Pen pen = new Pen(Color.Green, 3);
graphics.DrawEllipse(pen, 10, 10, 100, 100);

// 繪製文字
var font = new Font("JetBrainsMono NF", 36);
var textColor = Color.FromArgb(250, 95, 11);
graphics.DrawString("Ruyut", font, new SolidBrush(textColor), 130, 30);
    



參考資料:
Microsoft.Learn - How to: Use Clipping with a Region

留言