Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 我怎样才能变得简单;块;GDI和x2B的概要;路径_Windows_Graphics_Gdi+ - Fatal编程技术网

Windows 我怎样才能变得简单;块;GDI和x2B的概要;路径

Windows 我怎样才能变得简单;块;GDI和x2B的概要;路径,windows,graphics,gdi+,Windows,Graphics,Gdi+,假设我有一个相对复杂的GDI+GraphicsPath,里面有“洞”。文本就是一个很好的例子,就像字母“O”一样。我想改变这条路径,这样我就可以完全填充它,包括“洞”。我该怎么做 我用德尔菲提出了一个局部解决方案。它仅适用于整个路径“包含”在单个子路径中的情况。它只是迭代子路径并返回与最大子路径相同的新路径。它不是上述问题的通用解决方案,但它适用于当前的案例,并可能在将来帮助其他人: function BlockPath(Path: IGPGraphicsPath): IGPGraphicsPa

假设我有一个相对复杂的GDI+GraphicsPath,里面有“洞”。文本就是一个很好的例子,就像字母“O”一样。我想改变这条路径,这样我就可以完全填充它,包括“洞”。我该怎么做


我用德尔菲提出了一个局部解决方案。它仅适用于整个路径“包含”在单个子路径中的情况。它只是迭代子路径并返回与最大子路径相同的新路径。它不是上述问题的通用解决方案,但它适用于当前的案例,并可能在将来帮助其他人:

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;
}