Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   TPNGImage in TGPImage umwandeln (https://www.delphipraxis.net/191959-tpngimage-tgpimage-umwandeln.html)

SiLo0815 7. Mär 2017 16:05

TPNGImage in TGPImage umwandeln
 
Hallo,

ich möchte ein TPNGImage in ein TGPImage (GDI+ Library, http://www.bilsen.com/gdiplus/index.shtml) umwandeln.
Mein bisheriger Ansatz sieht so aus:

1. PNG laden
2. PNG in TMemoryStream speichern
3. TGPImage aus diesem Stream erzeugen.
(4. Bild zeichnen)

Folgender Code wirft allerdings eine EInvalidPointer Exception:

Delphi-Quellcode:
procedure TForm2.btn11Click(Sender: TObject);
var
   PNGImage: TPNGImage;
   ImageStream: TMemoryStream;
   Image: IGPImage;
   G: IGPGraphics;
begin
   // PNG erstellen & laden
   PNGImage := TPNGImage.Create;
   PNGImage.LoadFromFile('[Dateipfad]');
   ImageStream := TMemoryStream.Create;

   // PNG in Stream speichern
   PNGImage.SaveToStream(ImageStream);

   // TGPImage von Stream erzeugen
   Image := TGPImage.FromStream(TStreamAdapter.Create(ImageStream));

   // TGPImage zeichnen
   G := TGPGraphics.Create(pbButtonTest.Canvas.Handle);
   G.DrawImage(Image, 0, 0);
end;
Dem Stacktrace zufolge sieht es so aus, als würde das Destroy vom StreamAdapter den Fehler verursachen. Was genau mache ich falsch?

Grüße
Simon

nahpets 7. Mär 2017 19:04

AW: TPNGImage in TGPImage umwandeln
 
Funktioniert dieses eventuell so?
Delphi-Quellcode:
procedure TForm2.btn11Click(Sender: TObject);
var
   PNGImage: TPNGImage;
   Image: IGPImage;
begin
   PNGImage := TPNGImage.Create;
   PNGImage.LoadFromFile('[Dateipfad]');
   Image := IGPImage.Create;
   Image.Picture.Bitmap.Assign(PNGImage);
   ...

SiLo0815 7. Mär 2017 19:36

AW: TPNGImage in TGPImage umwandeln
 
Hi Stephan,

danke für deine Antwort!

Leider funktioniert es so nicht. Schon am
Delphi-Quellcode:
Image := IGPImage.Create
scheitert es mit E2018 "Record, Objekt oder Klassentyp erforderlich", weil IGPImage ein Interface ist.
Ich verwende übrigens diese Library: http://www.bilsen.com/gdiplus/index.shtml (das hätte ich vielleicht im Anfangspost schon erwähnen sollen, sorry. :roll:)

Eigentlich sollte sich TGPImage selbst um den Stream kümmern, der ihm im Konstruktor übergeben wird, oder?!
Meine Versuche den TStreamAdapter aus dem Konstruktor auszulagern und selbst Free aufzurufen, nachdem das Image nicht mehr benötigt wird, scheitern mit einer AccessViolation.
Ich bin etwas ratlos, auch weil ich mit Interfaces bisher eher wenig zu tun hatte. Vielleicht liegt der Fehler ja auch in der Library selbst, aber bei 17.000 Zeilen Fremdcode muss ich leider kapitulieren. Deswegen hatte ich gehofft, dass ich einfach etwas Simples übersehen habe.

Grüße
Simon

Uwe Raabe 7. Mär 2017 20:07

AW: TPNGImage in TGPImage umwandeln
 
Der IStream-Parameter von FromStream ist als
Delphi-Quellcode:
const
deklariert. Das setzt die Referenzzählung außer Kraft. Eine lokale IStream-Variable schafft hier Abhilfe.

Delphi-Quellcode:
       stream := TStreamAdapter.Create(ImageStream);

       // TGPImage von Stream erzeugen
       Image := TGPImage.FromStream(stream);

SiLo0815 7. Mär 2017 20:25

AW: TPNGImage in TGPImage umwandeln
 
Vielen, vielen Dank Uwe, es funktioniert!
Ahh, den halben Tag habe ich daran gesessen und die Lösung ist ein Einzeiler...
Ich werde mir wohl mal etwas Literatur zum Thema Referenzzählung zu Gemüte führen. :-D

Euch noch einen schönen Abend!

Fritzew 7. Mär 2017 22:31

AW: TPNGImage in TGPImage umwandeln
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1363469)
Der IStream-Parameter von FromStream ist als
Delphi-Quellcode:
const
deklariert. Das setzt die Referenzzählung außer Kraft. Eine lokale IStream-Variable schafft hier Abhilfe.

Delphi-Quellcode:
       stream := TStreamAdapter.Create(ImageStream);

       // TGPImage von Stream erzeugen
       Image := TGPImage.FromStream(stream);

Das ist ein Problem das schon wirklich oft aufgetreten ist, aber Embarcadero ignoriert das seit ewig. Bei anderen Managed Types funktioniert es bei interfaces nicht. Das könnte der compiler beheben.....
Und das es machbar ist wird zb mit Strings bewiesen. Es mag ein definiertes Verhalten sein aber das macht es nicht richtig.
Versuche das mal einem Neuling beizubringen....
(Ps: Uwe , ich denke das Problem ist Dir sehr wohl bekannt, ich habe vor Jahren mit Barry Kelly darüber gesprochen, Aussage : "They dont want it")

Uwe Raabe 7. Mär 2017 23:14

AW: TPNGImage in TGPImage umwandeln
 
Zitat:

Zitat von Fritzew (Beitrag 1363477)
Es mag ein definiertes Verhalten sein aber das macht es nicht richtig.

Ich bin auch kein Freund dieser Eigenart, aber ich weiß, daß dieses Feature manchmal benutzt wird, um die Referenzzählung bei Interface-Parametern zu umgehen. Eine Änderung würde da wohl eher verhalten begrüßt werden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:15 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz