Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Auf Canvas zeichnen, wenn PNG (https://www.delphipraxis.net/160327-auf-canvas-zeichnen-wenn-png.html)

Jazzman_Marburg 8. Mai 2011 14:24

Auf Canvas zeichnen, wenn PNG
 
Hallo Gemeinde,
ich habe mit (Delphi XE) myImage.Picture.LoadFromFile('Grafik.PNG') ein PNG-File geladen und versuche nun auf das gleiche Canvas ein myImage.Canvas.Rectangle(myRect) aber da bekomme ich einen Fehler:
EInvalidOpeartion: Ein Bild kann nur geändert werden, wenn es ein Bitmap enthält.

Klar ein PNG ist kein Bitmap, aber kann ich dann garnicht auf das Canvas zeichnen?
Muß das Ding irgendwie konvertiert werden (das veränderte PNG würde ich aber anschließend wieder gern als PNG speichern)?

Die Delphi-Hilfe sagt folgendes zu TPngImage:
Delphi-Quellcode:
procedure Draw(ACanvas: TCanvas; const Rect: TRect);
Draws the png image on a canvas.

Call Draw to draw the png image on a canvas. Draw considers transparency options when drawing the image, but ignores pixel information.
Aber ich verstehe den Hinweis auf TPngImage nicht -- Auf der Form habe ich ja nur das TImage, und dort habe ich das PNG-File mit LoadFromFile geladen.

Hat jemand wohl eine Idee, wie aich auf das Canvas des TImage malen kann, wenn es zuvor ein PNG geladen hat?

Vielen Dank im voraus
Gruß
Jazzman

Thom 8. Mai 2011 14:36

AW: Auf Canvas zeichnen, wenn PNG
 
TPNGImage(Image.Picure.Graphic).Canvas.xxx :gruebel:

Namenloser 8. Mai 2011 14:48

AW: Auf Canvas zeichnen, wenn PNG
 
Du musst das PNG erst auf ein Bitmap kopieren, zum Speichern umgekehrt:
Delphi-Quellcode:
var
  Bmp: TBitmap;
  Png: TPNGObject;
begin
  Bmp := nil;
  Png := nil;
  try
    Bmp := TBitmap.Create;
    Bmp.Assign(myImage.Picture.Graphic);
    Bmp.Canvas.…(…);

    Png := TPNGObject.Create;
    Png.Assign(Bmp);
    Png.SaveToFile(…);  
  finally
    Bmp.Free;
    Png.Free;
  end;
end;

Jazzman_Marburg 8. Mai 2011 14:56

AW: Auf Canvas zeichnen, wenn PNG
 
Zitat:

Zitat von Thom (Beitrag 1099555)
TPNGImage(Image.Picure.Graphic).Canvas.xxx :gruebel:

Der gleiche Fehler.

Jazzman

Jazzman_Marburg 8. Mai 2011 14:57

AW: Auf Canvas zeichnen, wenn PNG
 
Zitat:

Zitat von NamenLozer (Beitrag 1099557)
Du musst das PNG erst auf ein Bitmap kopieren, zum Speichern umgekehrt:
Delphi-Quellcode:
var
  Bmp: TBitmap;
  Png: TPNGObject;
begin
  Bmp := nil;
  Png := nil;
  try
    Bmp := TBitmap.Create;
    Bmp.Assign(myImage.Picture.Graphic);
    Bmp.Canvas.…(…);

    Png := TPNGImage.Create;
    Png.Assign(Bmp);
    Png.SaveToFile(…);  
  finally
    Bmp.Free;
    Png.Free;
  end;
end;

Super - vielen Dank!

Jazzman

Thom 8. Mai 2011 15:13

AW: Auf Canvas zeichnen, wenn PNG
 
Zitat:

Zitat von NamenLozer (Beitrag 1099557)
Du musst das PNG erst auf ein Bitmap kopieren, zum Speichern umgekehrt...

Das ist nicht korrekt.
Folgendes Beispiel funktioniert ohne Probleme:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Image1.Picture.LoadFromFile('xxx.png');
  with TPNGImage(Image1.Picture.Graphic) do
  begin
    Canvas.Brush.Color:=clRed;
    Canvas.Rectangle(10,10,50,50);
  end;
  Image1.Refresh;
end;
Wer's nicht glaubt: Ich kann die Demo gern anhängen...
Welche PNGImage-Version verwendest Du?

EWeiss 8. Mai 2011 15:21

AW: Auf Canvas zeichnen, wenn PNG
 
Zitat:

Zitat von Thom (Beitrag 1099562)
Zitat:

Zitat von NamenLozer (Beitrag 1099557)
Du musst das PNG erst auf ein Bitmap kopieren, zum Speichern umgekehrt...

Das ist nicht korrekt.
Folgendes Beispiel funktioniert ohne Probleme:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Image1.Picture.LoadFromFile('xxx.png');
  with TPNGImage(Image1.Picture.Graphic) do
  begin
    Canvas.Brush.Color:=clRed;
    Canvas.Rectangle(10,10,50,50);
  end;
  Image1.Refresh;
end;
Wer's nicht glaubt: Ich kann die Demo gern anhängen...
Welche PNGImage-Version verwendest Du?

Vor allem sollte man bedenken das bei den konvertieren der Alpha Channel verloren geht.
Oder?

gruss

Thom 8. Mai 2011 15:24

AW: Auf Canvas zeichnen, wenn PNG
 
Genau - das kommt auch noch als "Nebeneffekt" hinzu! :thumb:

EWeiss 8. Mai 2011 15:39

AW: Auf Canvas zeichnen, wenn PNG
 
Zitat:

Zitat von Thom (Beitrag 1099567)
Genau - das kommt auch noch als "Nebeneffekt" hinzu! :thumb:

Und dann macht es keinen Sinn mehr ein PNG einzuladen und darauf zu zeichnen.
Wenn es erst konvertiert werden muss.

gruss

Namenloser 8. Mai 2011 15:42

AW: Auf Canvas zeichnen, wenn PNG
 
Zitat:

Zitat von Thom (Beitrag 1099562)
Zitat:

Zitat von NamenLozer (Beitrag 1099557)
Du musst das PNG erst auf ein Bitmap kopieren, zum Speichern umgekehrt...

Das ist nicht korrekt.
Folgendes Beispiel funktioniert ohne Probleme:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Image1.Picture.LoadFromFile('xxx.png');
  with TPNGImage(Image1.Picture.Graphic) do
  begin
    Canvas.Brush.Color:=clRed;
    Canvas.Rectangle(10,10,50,50);
  end;
  Image1.Refresh;
end;
Wer's nicht glaubt: Ich kann die Demo gern anhängen...
Welche PNGImage-Version verwendest Du?

Hmm, vielleicht funktioniert das unter XE, früher (bei der OpenSource-Version) war TPNGObject.Canvas AFAIR Read-Only.
Inwiefern beim Kopieren der Alpha-Channel erhalten bleibt, weiß ich nicht sicher, aber prinzipiell hätte ein 32Bit-Bitmap Platz dafür.

Ich nutze für die Bearbeitung von PNGs aber eh immer Graphics32 mit der GR32_PNG-Unit...

EWeiss 8. Mai 2011 15:47

AW: Auf Canvas zeichnen, wenn PNG
 
Zitat:

Inwiefern beim Kopieren der Alpha-Channel erhalten bleibt, weiß ich nicht sicher, aber prinzipiell hätte ein 32Bit-Bitmap Platz dafür.
Starte mal ein Paint Programm ala PhotoShop
Konvertiere ein PNG nach Bitmap und siehe was dann vom alpha Channel noch übrigbleibt.

Ein Weißer Hintergrund mehr nicht... die Transparenz wird komplett entfernt.

gruss

Namenloser 8. Mai 2011 15:50

AW: Auf Canvas zeichnen, wenn PNG
 
Zitat:

Zitat von EWeiss (Beitrag 1099572)
Zitat:

Inwiefern beim Kopieren der Alpha-Channel erhalten bleibt, weiß ich nicht sicher, aber prinzipiell hätte ein 32Bit-Bitmap Platz dafür.
Starte mal ein Paint Programm ala PhotoShop
Konvertiere ein PNG nach Bitmap und siehe was dann vom alpha Channel noch übrigbleibt.

Ein Weißer Hintergrund mehr nicht... die Transparenz wird komplett entfernt.

Und was hat Photoshop mit Delphi zu tun?
Ich habe schon mit ganz normalen Bitmaps mit Alphachannel gearbeitet... war überhaupt kein Problem. Du darfst nur nicht die veralteten GDI-Routinen zum Zeichnen nutzen.

EWeiss 8. Mai 2011 15:56

AW: Auf Canvas zeichnen, wenn PNG
 
Zitat:

Zitat von NamenLozer (Beitrag 1099573)
Zitat:

Zitat von EWeiss (Beitrag 1099572)
Zitat:

Inwiefern beim Kopieren der Alpha-Channel erhalten bleibt, weiß ich nicht sicher, aber prinzipiell hätte ein 32Bit-Bitmap Platz dafür.
Starte mal ein Paint Programm ala PhotoShop
Konvertiere ein PNG nach Bitmap und siehe was dann vom alpha Channel noch übrigbleibt.

Ein Weißer Hintergrund mehr nicht... die Transparenz wird komplett entfernt.

Und was hat Photoshop mit Delphi zu tun?
Ich habe schon mit ganz normalen Bitmaps mit Alphachannel gearbeitet... war überhaupt kein Problem. Du darfst nur nicht die veralteten GDI-Routinen zum Zeichnen nutzen.

Kein Problem solange du es nicht von einem zum anderen konvertierst.
Teste es doch ganz einfach ;)

gruss

rollstuhlfahrer 8. Mai 2011 16:26

AW: Auf Canvas zeichnen, wenn PNG
 
Ich will mal GDI+ als Stichwort einwerfen. Da das PNG von Natur aus unterstützt, wird es wohl auch keine Probleme geben, wenn man mit den GDI+-Routinen auf das Bild malt.

Bernhard

Thom 8. Mai 2011 16:44

AW: Auf Canvas zeichnen, wenn PNG
 
Zitat:

Zitat von rollstuhlfahrer (Beitrag 1099576)
Da das PNG von Natur aus unterstützt, wird es wohl auch keine Probleme geben, wenn man mit den GDI+-Routinen auf das Bild malt.

Benötigst Du da nicht auch ein gültiges DC-Handle (TCanvas.Handle)? :gruebel:

Übrigens steht bei Delphi XE in der PNGImage-Unit
Delphi-Quellcode:
const
  LibraryVersion = '1.564';

  //...

  TPngImage = class{$IFDEF UseDelphi}(TGraphic){$ENDIF}
  //...
  public
  //...
    {Canvas}
    {$IFDEF UseDelphi}property Canvas: TCanvas read fCanvas;{$ENDIF}
  //...
  end.
Gibt es da evtl. zu älteren Versionen einen Unterschied?

Edit:
Ich hab's jetzt noch einmal mit Delphi 5 getestet, als TPNGImage noch TPNGObject hieß: Das Zeichnen auf den TPNGxxx-Canvas funktioniert definitiv!

Namenloser 8. Mai 2011 17:08

AW: Auf Canvas zeichnen, wenn PNG
 
Liste der Anhänge anzeigen (Anzahl: 1)
OK, ich habe es getestet:
  1. TPNGObject.Canvas ist tatsächlich beschreibbar
  2. Beim Assign geht der Alphachannel verloren (weil leider nicht „kopiert“ sondern gezeichnet wird (mit AlphaBlending))

@EWeiss: Das heißt aber nicht dass es nicht möglich wäre den AlphaChannel zu erhalten. PNGDelphi macht es nur einfach nicht, und die meisten Programme auch nicht.

Im Anhang befindet sich ein DUnit-TestProjekt, in dem auch eine Methode gezeigt wird, wie man den Alphachannel erhalten kann (man kann dann aber nicht die GDI zur Weiterverarbeitung nutzen). Das Rückkopieren von einem Bitmap in ein PNG geht ähnlich.

Aber wenn es auch direkt mit TPNGObject.Canvas geht, ist das natürlich eh unnötig...

rollstuhlfahrer 8. Mai 2011 17:16

AW: Auf Canvas zeichnen, wenn PNG
 
Zitat:

Zitat von Thom (Beitrag 1099577)
Benötigst Du da nicht auch ein gültiges DC-Handle (TCanvas.Handle)? :gruebel:

Kommt ganz drauf an, wie man das Bild lädt. In diesem Fall ist der beste Weg, ein GDIP-Image zu nehmen und dann mit Hilfe von .LoadFromFile() das Image zu laden. Dass man zeichnen kann, braucht man eine GDIP-Graphic. Diese kann man sich aus dem GDIP-Image erstellen lassen und schon kann man zeichnen.

Sicherheitshalber danach ein Graphic.Flush() ausführen, dass auch wirklich gezeichnet wurde und nicht nur die Aufträge dazu gegeben wurden.

Bernhard

EWeiss 8. Mai 2011 17:47

AW: Auf Canvas zeichnen, wenn PNG
 
Zitat:

Zitat von rollstuhlfahrer (Beitrag 1099576)
Cih will mal GDI+ als Stichwort einwerfen. Da das PNG von Natur aus unterstützt, wird es wohl auch keine Probleme geben, wenn man mit den GDI+-Routinen auf das Bild malt.

Bernhard

Jo so mache ich das ;)
Text auf ein PNG zeichen ist ja quasi das gleiche.

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:49 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