2011-01-04 5 views
3

GDI + GraphicsPathが比較的複雑で、その中に「穴」があるとします。テキストは、文字 "O"のような良い例です。私はこの道を変えて、「穴」を含めて完全に埋めることができるようにしたい。これどうやってするの?GDI +パスの簡単な「ブロック」アウトラインを取得するにはどうすればよいですか?

sample image

+0

+1興味深い質問です。確かに当初考えていたものより複雑です:) – leppie

+0

質問:パスとしてそれを保持する必要がありますか?ビットマップの結果が許容範囲内であれば、はるかに簡単になります。 –

+0

おそらくビットマップが機能するかもしれません。私はその解決方法をどちらかの方法で見ることに興味があります。 – jthurman

答えて

1

は、ここで私が思いついたことを、Delphiで、部分的なソリューションです。これは、パス全体が単一のサブパスに「包含」されている場合にのみ機能します。これは、単にサブパスを反復し、最大のサブパスと同じ新しいパスを返します。これは、上記の問題へのユニバーサルソリューションではありませんが、それは手でケースのために働く、そして将来的には他の誰かを助けるかもしれない:

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; 

コメントと改善は歓迎されています。

2

コーディ、

私はあなたがまだ答えを受け入れていたことを見ていなかったので、私はそれができますかどうかを確認するために、ここで、このC#の機能を入れています。それはテストされています。

上記のバージョンと少し違う:このルーチンは、最大の境界領域を持つパスを探します。したがって、2つのテストを渡すための "マスター"パスは必要ないため、上記バージョンより少し寛大です。それが維持する価値があることを証明する。

.NETであなただけ書くことができますので、私は、拡張メソッドにこれを作った:

GraphicsPath solid = LetterPath.ToSolidPath(); 

戻り値はその内部が骨抜きされた(すごい、私が使用して取得していない新しいGraphicsPathですその言葉は非常に頻繁に)。

/// <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; 
} 
関連する問題