Windows 我怎样才能变得简单;块;GDI和x2B的概要;路径
假设我有一个相对复杂的GDI+GraphicsPath,里面有“洞”。文本就是一个很好的例子,就像字母“O”一样。我想改变这条路径,这样我就可以完全填充它,包括“洞”。我该怎么做Windows 我怎样才能变得简单;块;GDI和x2B的概要;路径,windows,graphics,gdi+,Windows,Graphics,Gdi+,假设我有一个相对复杂的GDI+GraphicsPath,里面有“洞”。文本就是一个很好的例子,就像字母“O”一样。我想改变这条路径,这样我就可以完全填充它,包括“洞”。我该怎么做 我用德尔菲提出了一个局部解决方案。它仅适用于整个路径“包含”在单个子路径中的情况。它只是迭代子路径并返回与最大子路径相同的新路径。它不是上述问题的通用解决方案,但它适用于当前的案例,并可能在将来帮助其他人: function BlockPath(Path: IGPGraphicsPath): IGPGraphicsPa
我用德尔菲提出了一个局部解决方案。它仅适用于整个路径“包含”在单个子路径中的情况。它只是迭代子路径并返回与最大子路径相同的新路径。它不是上述问题的通用解决方案,但它适用于当前的案例,并可能在将来帮助其他人:
function BlockPath(Path: IGPGraphicsPath): IGPGraphicsPath;
var
PathIterator: IGPGraphicsPathIterator;
SubPath: IGPGraphicsPath;
I: Integer;
IsClosed: Boolean;
BiggestPath: IGPGraphicsPath;
BiggestRect, BoundsRect: TGPRectF;
begin
Result := TGPGraphicsPath.Create;
SubPath := TGPGraphicsPath.Create;
PathIterator := TGPGraphicsPathIterator.Create(Path);
PathIterator.Rewind;
BiggestPath := nil;
BiggestRect.Width := 0;
BiggestRect.Height := 0;
for I := 0 to PathIterator.SubpathCount - 1 do
begin
SubPath.Reset;
PathIterator.NextSubPath(SubPath, IsClosed);
SubPath.GetBounds(BoundsRect);
if (BoundsRect.Width >= BiggestRect.Width) and
(BoundsRect.Height >= BiggestRect.Height) then
begin
BiggestRect := BoundsRect;
BiggestPath := SubPath.Clone;
end;
end;
if BiggestPath <> nil then
begin
Result.AddPath(BiggestPath, True);
end;
end;
功能块路径(路径:IGPGraphicsPath):IGPGraphicsPath;
变量
路径迭代器:IGPGraphicsPathIterator;
子路径:IGPGH;
I:整数;
IsClosed:布尔型;
最大路径:IGPGH;
BiggestRect,BoundsRect:TGPRectF;
开始
结果:=TGPGraphicsPath.Create;
子路径:=TGPGraphicsPath.Create;
PathIterator:=tgpgraphicspathierator.Create(路径);
倒带;
最大路径:=nil;
最大直接宽度:=0;
最大直接高度:=0;
对于I:=0到PathIterator.SubpathCount-1 do
开始
子路径重置;
PathIterator.NextSubPath(子路径,IsClosed);
子路径GetBounds(BoundsRect);
如果(BoundsRect.Width>=BiggestRect.Width)和
(BoundsRect.Height>=BiggestRect.Height)然后
开始
BiggestRect:=BoundsRect;
BiggestPath:=子路径克隆;
结束;
结束;
如果最大路径为零,则
开始
Result.AddPath(BiggestPath,True);
结束;
结束;
欢迎评论和改进。Cody
我还没有看到你已经接受了答案,所以我把这个C#函数放在这里让你看看它是否有用。它已经过测试
与上面的版本稍有不同:此例程查找具有最大边界区域的路径,因此它比上面的版本稍微宽松一些,因为它不需要“主”路径通过2个测试来证明它值得保留
我将其制作成一个扩展方法,因此在.Net中,您可以编写:
GraphicsPath solid = LetterPath.ToSolidPath();
返回值是一个新的GraphicsPath,其内部已被取出内脏(哇,我不经常使用这个词)
//
///从图形路径中删除所有子路径(孔),只留下最大的整个路径
///
公共静态GraphicsPath到SolidPath(此GraphicsPath)
{
GraphicsPath BiggestPath=null;
GraphicsPath SubPath=新的GraphicsPath();
矩形F边界Rect=矩形F.为空;
RectangleF BiggestRect=矩形f.空;
bool-biscolled=false;
var pathIterator=新的GraphicsPathIterator(路径);
pathIterator.Rewind();
for(int i=0;iBiggestRect.Width*BiggestRect.Height)
{
BiggestRect=BoundsRect;
BiggestPath=(GraphicsPath)SubPath.Clone();
}
}
返回最大路径;
}
+1个有趣的问题。确实比人们最初想象的要复杂:)问题:是否有必要将其保留为一条路径?如果位图结果是可以接受的,它会变得容易得多。也许位图可以工作。我有兴趣看到这种解决方案。
/// <summary>
/// Removes all subpaths (holes) from a graphics path, leaving only the largest whole path behind
/// </summary>
public static GraphicsPath ToSolidPath(this GraphicsPath path)
{
GraphicsPath BiggestPath = null;
GraphicsPath SubPath = new GraphicsPath();
RectangleF BoundsRect = RectangleF.Empty;
RectangleF BiggestRect = RectangleF.Empty;
bool bIsClosed = false;
var pathIterator = new GraphicsPathIterator(path);
pathIterator.Rewind();
for (int i = 0; i < pathIterator.SubpathCount; i++)
{
SubPath.Reset();
pathIterator.NextSubpath(SubPath, out bIsClosed);
BoundsRect = SubPath.GetBounds();
if (BoundsRect.Width * BoundsRect.Height > BiggestRect.Width * BiggestRect.Height)
{
BiggestRect = BoundsRect;
BiggestPath = (GraphicsPath)SubPath.Clone();
}
}
return BiggestPath;
}