如何填充排除某些区域(路径)的路径C#图形

时间:2018-09-04 18:11:18

标签: c# winforms graphics dlib

现在正在开发Windows窗体C#App,它使用dlib(https://github.com/takuya-takeuchi/DlibDotNet)检测到您的脸
点可获取68个人脸地标

具有以下特征的地标:enter image description here

因此,我为此绘制了一条针对嘴唇,鼻子,眼睛和眉毛的图形路径,以及一条遍及整个面部的路径,我的问题是,是否可以减去眼睛,眉毛,嘴唇和鼻子的路径从覆盖所有脸部的那一面来绘制所有“排除”那些区域的脸部?

我发现这在xaml中是可能的:

https://docs.microsoft.com/en-us/visualstudio/designers/draw-shapes-and-paths?view=vs-2017enter image description here

那么可以在C#中使用图形路径和位图来执行ExcludeOverlap或Substract吗? 如果可以的话?

(我知道发布一些代码几乎是一条潜规则,但是我基本上所做的就是为面部的每个部分创建一个图形路径,然后使用Graphics.FillPath()将它们绘制在位图上。

1 个答案:

答案 0 :(得分:0)

是否可以从覆盖整个脸部的脸上减去眼睛,眉毛,嘴唇和鼻子的路径,以绘制所有“排除”那些区域的脸部?

这不仅可行;实际上,这是组合GraphicsPaths的默认设置:您将较小的内部路径添加到较大的外部路径中,并且在进行填充时它们将成为孔。

但是,当您在“孔”上覆盖更多路径而导致孔内出现正区域时,也会发生这种情况。

要使所有路径相加( -ing),您可以将FillMode属性更改为Winding。默认值是“ Alternative”(替代),它将创建孔( Xor -将阿拉伯符号化。)

要获得完全控制权,您可以使用Regions。它们可以与整套设置操作随意组合。但是它们不支持抗锯齿,因此曲线和倾斜的线条看起来会很粗糙。

示例:

enter image description here

private void pictureBox2_Paint(object sender, PaintEventArgs e)
{
    GraphicsPath gp0 = new GraphicsPath();
    GraphicsPath gp1 = new GraphicsPath();
    GraphicsPath gp2 = new GraphicsPath();
    GraphicsPath gp3 = new GraphicsPath();
    GraphicsPath gp4 = new GraphicsPath();

    gp0.AddEllipse(11, 11, 333, 333);
    gp1.AddEllipse(55, 55, 55, 55);
    gp2.AddEllipse(222, 55, 66, 66);
    gp3.AddEllipse(55, 222, 99, 222);
    gp4.AddLine(66, 123, 234, 77);

    using (Pen pen = new Pen(Color.Empty, 12f))
    gp4.Widen(pen);

    gp0.AddPath(gp1, true);
    gp0.AddPath(gp2, true);
    gp0.AddPath(gp3, true);
    gp0.AddPath(gp4, true);

    gp0.FillMode = FillMode.Alternate;
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    e.Graphics.FillPath(Brushes.Goldenrod, gp0);
}