You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF中如何让Geometry向内收缩1像素并动态获取结果Path?

WPF中如何让Geometry向内收缩1像素并动态获取结果Path?

嘿,这个问题我之前做自定义形状的时候刚好踩过坑!在WPF里要让不规则Geometry向内收缩固定像素,确实没有直接的API,但可以通过几何组合的方式实现,下面给你详细讲步骤和代码:

首先得明确:向内收缩1像素,相当于给原闭合路径的内侧生成一个偏移1像素的新轮廓。核心思路是利用GetWidenedPathGeometry生成加宽的路径环,再通过几何组合得到内部的收缩区域。

实现步骤&代码

  1. 确保原Geometry是闭合的:如果原路径是未闭合的线条,得先把它闭合,否则几何组合会出错。
  2. 生成加宽路径环:用一个厚度为2像素的Pen(因为要向内缩1,这个Pen会向原路径的内外各扩展1像素),通过GetWidenedPathGeometry得到原路径的轮廓加宽后的环形区域。
  3. 几何组合取内部收缩区域:用原几何减去这个环形区域,剩下的就是向内收缩1像素后的结果。

这里是封装好的工具方法,亲测有效:

/// <summary>
/// 将Geometry向内收缩指定像素
/// </summary>
/// <param name="originalGeometry">原几何图形</param>
/// <param name="shrinkPixels">收缩像素值</param>
/// <returns>收缩后的几何图形</returns>
public static Geometry ShrinkGeometry(Geometry originalGeometry, double shrinkPixels)
{
    if (originalGeometry == null || shrinkPixels <= 0)
        return originalGeometry;

    // 1. 确保原几何是闭合的
    Geometry closedGeometry = originalGeometry;
    if (!originalGeometry.IsFilled)
    {
        PathGeometry flattened = originalGeometry.GetFlattenedPathGeometry();
        if (flattened.Figures.Count > 0)
        {
            foreach (PathFigure figure in flattened.Figures)
            {
                if (!figure.IsClosed)
                {
                    figure.IsClosed = true;
                }
            }
            closedGeometry = flattened;
        }
    }

    // 2. 创建Pen,厚度为2倍收缩值(向内外各扩展shrinkPixels)
    Pen offsetPen = new Pen
    {
        Thickness = shrinkPixels * 2,
        LineJoin = LineJoin.Round, // 保持拐角平滑,可换成Bevel/Miter保留尖锐拐角
        StartLineCap = PenLineCap.Round,
        EndLineCap = PenLineCap.Round
    };

    // 3. 获取加宽后的环形几何
    Geometry widenedGeometry = closedGeometry.GetWidenedPathGeometry(offsetPen);

    // 4. 组合几何:原实心区域减去环形,得到内部收缩后的区域
    Geometry shrunkGeometry = Geometry.Combine(closedGeometry, widenedGeometry, GeometryCombineMode.Exclude, null);
    return shrunkGeometry;
}

动态生成收缩后的Path

有了上面的方法,你就可以动态创建目标Path了:

// 假设你已有原Path对象originalPath
Geometry shrunkGeo = ShrinkGeometry(originalPath.Data, 1);
Path bluePath = new Path
{
    Data = shrunkGeo,
    Fill = Brushes.Blue,
    Stroke = Brushes.Black,
    StrokeThickness = 1
};
// 把bluePath添加到你的布局容器(比如Grid、Canvas)中即可

注意事项

  • 这个方法对复杂不规则形状同样有效,因为它是基于几何运算的,不是简单的边界缩放。
  • LineJoin的设置会影响拐角处的收缩效果:Round让拐角更平滑,Miter保持尖锐拐角,按需调整即可。
  • 如果原路径是未闭合的线条,一定要先闭合它,否则几何组合会得到不符合预期的结果。

备注:内容来源于stack exchange,提问作者Developer333

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 12:27:45