WPF中如何让Geometry向内收缩1像素并动态获取结果Path?
WPF中如何让Geometry向内收缩1像素并动态获取结果Path?
嘿,这个问题我之前做自定义形状的时候刚好踩过坑!在WPF里要让不规则Geometry向内收缩固定像素,确实没有直接的API,但可以通过几何组合的方式实现,下面给你详细讲步骤和代码:
首先得明确:向内收缩1像素,相当于给原闭合路径的内侧生成一个偏移1像素的新轮廓。核心思路是利用GetWidenedPathGeometry生成加宽的路径环,再通过几何组合得到内部的收缩区域。
实现步骤&代码
- 确保原Geometry是闭合的:如果原路径是未闭合的线条,得先把它闭合,否则几何组合会出错。
- 生成加宽路径环:用一个厚度为2像素的Pen(因为要向内缩1,这个Pen会向原路径的内外各扩展1像素),通过
GetWidenedPathGeometry得到原路径的轮廓加宽后的环形区域。 - 几何组合取内部收缩区域:用原几何减去这个环形区域,剩下的就是向内收缩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
相关产品推荐
相关产品推荐

