2016-04-22 19 views
0

Ich verwende Mitovs IGDIPlus-Bibliothek für Delphi. Ich bekomme Exception "Generic Error" in einer völlig unschuldigen Situation. Ich habe fünf überlappende Rechtecke und möchte aPath.outline() verwenden, um den Umrißpfad zu finden (ich führe dieses Beispiel auf Win7, wobei alle umreißbezogenen Patches angewendet werden).gdiplus Pfad GdipWindingModeOutline Probleme

uses 
System.Types, IGDIPlus, VCL.IGDIPlusExt; 


procedure TForm1.FormPaint(Sender: TObject); 
var 
    AGraphics  : IGPGraphics; 
    APath,aPathO : IGPGraphicsPath; 

begin 
    AGraphics := TIGPGraphics.Create(Canvas); 
    AGraphics.SmoothingMode := SmoothingModeAntiAlias; 
    AGraphics.TextRenderingHint := TextRenderingHintAntiAlias; 
    aPath := TIGPGraphicsPath.create() ; 
    // this path gives generic error 
    aPath.addRectangle(73,201,108,96); 
// --------the difference---------- 
    aPath.addRectangle(73,292,58,96); 
// --------the difference---------- 
    aPath.addRectangle(73,383,108,96); 
    aPath.addRectangle(177,201,108,96); 
    aPath.addRectangle(177,383,108,96); 

    try 
    aPathO := apath.clone().Outline(); 
    AGraphics.DrawPath(TIGPPen.Create(aclRed,1), 
     aPathO); 
    except 
    on E: Exception do 
    begin 
     AGraphics.DrawStringF(e.message, 
          TIGPFont.Create('Microsoft Sans Serif', 16, [ fsBold ]), 
          TPointF.Create(23, 23), 
          TIGPSolidBrush.Create(aclRed)) ; 

     AGraphics.DrawPath(TIGPPen.Create(aclRed,1), 
     aPath); 
    end; 
    end; 
    aPath.reset(); 
// this path works fine 
    aPath.addRectangle(373,201,108,96); 
// --------the difference---------- 
    aPath.addRectangle(373,292,108,96);  
// --------the difference---------- 
    aPath.addRectangle(373,383,108,96); 
    aPath.addRectangle(477,201,108,96); 
    aPath.addRectangle(477,383,108,96); 

    try 
    aPathO := apath.clone().Outline(); 
    AGraphics.DrawPath(TIGPPen.Create(aclRed,1), 
     aPathO); 
    AGraphics.DrawStringF('it works', 
          TIGPFont.Create('Microsoft Sans Serif', 16, [ fsBold ]), 
          TPointF.Create(423, 23), 
          TIGPSolidBrush.Create(aclRed)) ; 

    except 
    on E: Exception do 
    begin 
     AGraphics.DrawStringF(e.message, 
          TIGPFont.Create('Microsoft Sans Serif', 16, [ fsBold ]), 
          TPointF.Create(223, 23), 
          TIGPSolidBrush.Create(aclRed)) ; 

     AGraphics.DrawPath(TIGPPen.Create(aclRed,1), 
     aPath); 
    end; 
    end; 
end; 

Alle Ideen, Anregungen sind willkommen.

das gleiche Beispiel in C# Lauf gibt den gleichen Fehler



    GraphicsPath aPath = new GraphicsPath(); 
       aPath.AddRectangle(new Rectangle(73, 201, 108, 96)); 
       aPath.AddRectangle(new Rectangle(73, 292, 58, 96)); 
       aPath.AddRectangle(new Rectangle(73, 383, 108, 96)); 
       aPath.AddRectangle(new Rectangle(177, 201, 108, 96)); 
       aPath.AddRectangle(new Rectangle(177, 383, 108, 96)); 

       HandleRef handle = new HandleRef(aPath, (IntPtr)aPath.GetType().GetField("nativePath", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(aPath)); 
       try 
       { 

        int status = GdipWindingModeOutline(handle, IntPtr.Zero, 0.25F); 
        using (Pen outlinePen = new Pen(Color.FromArgb(255, Color.Red), 2)) 
        { 
         g.DrawPath(outlinePen, aPath); 
        } 
       } 

       catch (Exception exp) 
       { ... 
       } 

GdipWindingModeOutline Funktion gibt status = 1 (Allgemeiner Fehler)

Weil ich wirklich die Umrisse Kurve verwenden müssen (Outline a path with GDI+ in .Net verwenden) und die Direkter Weg aPath.clone().outline() ist wegen GDI + Fehler unmöglich, ich muss gehen. Die passende Lösung - vielleicht nicht die beste, aber funktioniert - könnte sein:



     procedure TForm1.FormPaint(Sender: TObject); 
     var 
      AGraphics  : IGPGraphics; 
      APath,aPathO : IGPGraphicsPath; 
      aRegion   : IGPRegion; 
      aScan   : TArray; 
      aMatrix   : IGPmatrix; 

     begin 
      AGraphics := TIGPGraphics.Create(Canvas); 
      AGraphics.SmoothingMode := SmoothingModeAntiAlias; 
      AGraphics.TextRenderingHint := TextRenderingHintAntiAlias; 
      aPath := TIGPGraphicsPath.create() ; 
      aRegion := TIGPRegion.create().MakeEmpty(); 
      aRegion.Union( TIGPRect.create(73,201,108,96)); 
      aRegion.Union( TIGPRect.create(73,292,58,96)); 
      aRegion.Union( TIGPRect.create(73,383,108,96)); 
      aRegion.Union( TIGPRect.create(177,201,108,96)); 
      aRegion.Union( TIGPRect.create(177,383,108,96)); 
      aMatrix := TIGPMatrix.Create(); 
      aScan := lRegion.GetRegionScans(aMatrix); 
      for i := 0 to High(aScan) do 
      aPath.addRectangle(GPInflateRect(aScan[i], 1)); 


      aPathO := aPath.Clone().Outline(); 
      AGraphics.DrawPath(TIGPPen.Create(aclRed,1), aPathO); 

     end; 

Antwort

0

Ihre Linie AGraphics.DrawPath(TIGPPen.Create(aclRed,1), ... in Teh Delphi Welt gefährlich ist, wenn Sie Schnittstellen verwenden (was diese Bibliothek offensichtlich der Fall ist). Delphi hat einige Probleme, wenn es um Referenzzählung und Objekterstellung innerhalb von Funktionsaufrufen geht (ich erinnere mich nicht, aber ...). Versuchen Sie, das Objekt nicht innerhalb des Funktionsaufrufs zu erstellen, sondern definieren Sie eine neue lokale Variable, die das enthält Verweis auf die Schnittstelle.

+0

Nein, das Problem ist nicht in dieser Zeile (der Code basiert auf Mitov Demo), der generische Fehler zählt aus der Zeile über 'aPathO: = apath.clone(). Outline();' Es wäre Hilfreich, wenn jemand versucht hat, ein ähnliches Beispiel in C# oder einer anderen Sprache auszuführen – EvaF