AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls [Firemonkey] Canvas als PNG mit Transparenz speichern
Thema durchsuchen
Ansicht
Themen-Optionen

[Firemonkey] Canvas als PNG mit Transparenz speichern

Ein Thema von milos · begonnen am 11. Apr 2016 · letzter Beitrag vom 12. Apr 2016
Antwort Antwort
Benutzerbild von milos
milos

Registriert seit: 14. Jul 2008
Ort: Bern (CH)
509 Beiträge
 
Delphi 11 Alexandria
 
#1

[Firemonkey] Canvas als PNG mit Transparenz speichern

  Alt 11. Apr 2016, 23:26
Hallo,

ich habe eine Firemonkey anwendung bei der der User auf ein TImage Canvas Zeichnen kann.
Wie kann ich diese nun als PNG speichern lassen ohne das ich die Transparenz auf der nicht gezeichneten Fläche verliere?

Freundliche Grüsse

Edit:
Ich hätte eigentlich gedacht das es so funktionieren sollte:
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
  LBitmap : TBitmap;
begin
  Image1.Bitmap.SaveToFile('./tmp.bmp');
end;

procedure TForm1.Image1Paint(Sender: TObject; Canvas: TCanvas;
  const [Ref] ARect: TRectF);
begin
  Canvas.Fill.Color := $ffff0000;
  Canvas.FillRect(RectF(0,0,50,50),0,0,[],1);
end;
Aber hier wird mir nur eine leere bmp datei abgespeichert :/
Milos

Geändert von milos (11. Apr 2016 um 23:38 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

AW: [Firemonkey] Canvas als PNG mit Transparenz speichern

  Alt 11. Apr 2016, 23:41
Dein Code zeichnet auf das Canvas vom Formular und nicht auf das vom Bitmap, oder?
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von milos
milos

Registriert seit: 14. Jul 2008
Ort: Bern (CH)
509 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: [Firemonkey] Canvas als PNG mit Transparenz speichern

  Alt 11. Apr 2016, 23:47
Dein Code zeichnet auf das Canvas vom Formular und nicht auf das vom Bitmap, oder?
Sicher? Weil das gezeichnete Rectangle startet genau dort wo auch das TImage ist und wenn ich den Code so schreibe ändert sich das Ergebnis leider auch nicht :/

Delphi-Quellcode:
procedure TForm1.Image1Paint(Sender: TObject; Canvas: TCanvas;
  const [Ref] ARect: TRectF);
begin
  Image1.Canvas.Fill.Color := $ffff0000;
  Image1.Canvas.FillRect(RectF(0,0,50,50),0,0,[],1);
end;
Was ich noch versucht habe ist:

Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
  LBitmap : TBitmap;
begin
  LBitmap := TBitmap.Create;
  LBitmap.Width := Image1.Bitmap.Width;
  LBitmap.Height := Image1.Bitmap.Height;

  Image1.Canvas.CopyBitmap(Image1.Bitmap, LBitmap);

  LBitmap.SaveToFile('./tmp.bmp');
end;

procedure TForm1.Image1Paint(Sender: TObject; Canvas: TCanvas;
  const [Ref] ARect: TRectF);
begin
  Image1.Bitmap.Width := round(Image1.Width);
  Image1.Bitmap.Height := round(Image1.Height);
  Canvas.Fill.Color := $ffff0000;
  Canvas.FillRect(RectF(0,0,50,50),0,0,[],1);
end;
Das speichert mir keine leere Datei mehr (also 0 bytes) sondern eine Datei die zwar 100x100 hat aber einfach nur schwarz ist und keinerlei Spuren der gezeichneten Dinge enthält.

Das kann doch nicht so schwer sein, irgendwo muss da ein Wurm oder Denkfehler drin sein auch wenn ich beim besten Willen nicht sehe wo der ist :/

Freundliche Grüsse
Milos
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.093 Beiträge
 
Delphi 12 Athens
 
#4

AW: [Firemonkey] Canvas als PNG mit Transparenz speichern

  Alt 12. Apr 2016, 07:15
Wenn du ein Bmp hast könntest du damit Speichern
Delphi-Quellcode:
procedure S4Bmp_ToStream( bmpSrc : TBitmap;
                          strmDst : TStream;
                          sExt : String;
                          iQuality : Integer);
var
  Surf : TBitmapSurface;
  vBitMapData : TBitmapData;
  saveParams : TBitmapCodecSaveParams;

begin
  Surf := TBitmapSurface.Create;

  // lock and get the bitmap pixels
  if bmpSrc.Map(TMapAccess.Read, vBitMapData) then
  begin

      try
        Surf.Assign(bmpSrc);

        saveparams.Quality := iQuality; // 85;

        if not TBitmapCodecManager.SaveToStream(strmDst, Surf, sExt, @saveParams) then //'.jpg') then
            raise EBitmapSavingFailed.Create(
                  'Error saving Bitmap to ' + sExt);
    // raise EBitmapSavingFailed.Create(SBitmapSavingFailed);
      finally
        Surf.Free;
      end;


      bmpSrc.Unmap(vBitMapData); // unlock the bitmap

  end;

end;


// Aufruf mit Quality in %
S4Bmp_ToStream( bmpSrc, FileStream_als_Beispiel, '.png', 85);
Info: Den äussere Scope mit Bitmap.Map()... könnte man wohl auch weglassen,
ich hatte das noch von einem Test mit drin, aber ich denke das schadet auch nicht wenn es drin bleibt.


Eigentlich sollte das Canvas-Bitmap die Transparenz richtig drinhaben, müsstest du mal Testen.

Rollo

Geändert von Rollo62 (12. Apr 2016 um 07:18 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von milos
milos

Registriert seit: 14. Jul 2008
Ort: Bern (CH)
509 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: [Firemonkey] Canvas als PNG mit Transparenz speichern

  Alt 12. Apr 2016, 15:12
Hallo,

danke für die antwort!
Leider bekomme ich damit wieder eine Leere Datei die aber die richtige grösse hat, jedoch keine gezeichneten Pixel enthält.

Ich zeichne nun direkt auf ein Bitmap und rufe deine Funktion so auf:
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
  LBitmap : TBitmap;
  LStream : TFileStream;
begin
  LBitmap := TBitmap.Create; // erstelle bitmap
  LBitmap.Width := 50; // setze grösse
  LBitmap.Height := 50;

  LBitmap.Canvas.Fill.Color := $FFFF0000; // brush color auf rot setzen

  LBitmap.Canvas.DrawRect(RectF(0,0,10,50),0,0,[],1); // rectangle zeichnen

  LStream := TFileStream.Create('./DP.png', fmCreate or fmOpenWrite); // file stream erstellen

  S4Bmp_ToStream( LBitmap, LStream, '.png', 85); // funktionsaufruf
end;
Mache ich was falsch?

Im Anhang habe ich noch die DP.png angehängt die erzeugt wird. Sie ist da, aber eben halt ein leeres Bild... :/

Freundliche Grüsse und vielen dank für die Hilfe
Angehängte Grafiken
 
Milos
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.533 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: [Firemonkey] Canvas als PNG mit Transparenz speichern

  Alt 12. Apr 2016, 18:32
Vielleicht erst mal was grundsätzliches: Intern verwendet FMX immer eine 32-bit Bitmap, also mit Transparenz. Wenn Du das speicherst, reicht es einen Dateityp zu wählen, der Transparenz kann (also z.B. '.png'), die Transparenz bleibt dann automatisch erhalten.

Zu Deinem Code: Ohne Beginscene und Endscene wirst Du i.d.R. nichts sehen.

Hier ein kleines Beispiel, das ein rotgefülltes Rundeck erzeugt. Wenn Du das dann mit dem Button "Speichere" speicherst und die Datei in einem Bildbearbeitungsprogramm öffnest, sieht das so wie in der Anlage aus (Transparenz wird durch das Schachmuster signalisiert).

Außerdem musst Du drauf achten, auf welchen Canvas Du Dich beziehst (also nicht den Form-Canvas verwenden).

Delphi-Quellcode:
unit Unit18;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects,
  FMX.StdCtrls, FMX.Edit, FMX.Controls.Presentation;

type
  TForm18 = class(TForm)
    Image1: TImage;
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form18: TForm18;

implementation

{$R *.fmx}

procedure TForm18.Button1Click(Sender: TObject);
begin
  with image1.Bitmap.Canvas do begin
    if beginscene then begin
      try
        Fill.Color := TAlphaColorRec.red;
        FillRect(rectF (20,20, 100,100), 30,30,AllCorners,100);
      finally
        endscene;
      end;
    end;
  end;
end;

procedure TForm18.Button2Click(Sender: TObject);
begin
  image1.Bitmap.SaveToFile('D:\Test.png');
end;

procedure TForm18.FormCreate(Sender: TObject);
begin
  image1.Bitmap.SetSize(Round (image1.Width), Round (image1.Height));
end;

end.
Miniaturansicht angehängter Grafiken
testbild.jpg   progi.jpg  

Geändert von Harry Stahl (12. Apr 2016 um 18:38 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von milos
milos

Registriert seit: 14. Jul 2008
Ort: Bern (CH)
509 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: [Firemonkey] Canvas als PNG mit Transparenz speichern

  Alt 12. Apr 2016, 18:58
Vielleicht erst mal was grundsätzliches: Intern verwendet FMX immer eine 32-bit Bitmap, also mit Transparenz. Wenn Du das speicherst, reicht es einen Dateityp zu wählen, der Transparenz kann (also z.B. '.png'), die Transparenz bleibt dann automatisch erhalten.

Zu Deinem Code: Ohne Beginscene und Endscene wirst Du i.d.R. nichts sehen.

Hier ein kleines Beispiel, das ein rotgefülltes Rundeck erzeugt. Wenn Du das dann mit dem Button "Speichere" speicherst und die Datei in einem Bildbearbeitungsprogramm öffnest, sieht das so wie in der Anlage aus (Transparenz wird durch das Schachmuster signalisiert).

Außerdem musst Du drauf achten, auf welchen Canvas Du Dich beziehst (also nicht den Form-Canvas verwenden).
Danke Harry, das war der entscheidende Tipp und es funktioniert nun einwandfrei!

Vielen vielen dank, dachte mir schon das da etwas kleines aber wichtiges fehlt... Mir standen schon die Haare zu berge!

Freundliche Grüsse
Milos
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.093 Beiträge
 
Delphi 12 Athens
 
#8

AW: [Firemonkey] Canvas als PNG mit Transparenz speichern

  Alt 12. Apr 2016, 19:07
Du solltest dir meinen Vorschlag auch nochmal ansehen, denn nicht alle Plattformen unterstützen alle Formate.

http://docwiki.embarcadero.com/Libra...aphics.TBitmap

http://docwiki.embarcadero.com/Libra...te_Bildformate

Rollo
  Mit Zitat antworten Zitat
Benutzerbild von milos
milos

Registriert seit: 14. Jul 2008
Ort: Bern (CH)
509 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: [Firemonkey] Canvas als PNG mit Transparenz speichern

  Alt 12. Apr 2016, 21:04
Du solltest dir meinen Vorschlag auch nochmal ansehen, denn nicht alle Plattformen unterstützen alle Formate.

http://docwiki.embarcadero.com/Libra...aphics.TBitmap

http://docwiki.embarcadero.com/Libra...te_Bildformate

Rollo
Guter Hinweis.

Sobald ich mit Begin/EndScene arbeite kann ich auch ohne Probleme mit TBitmapSufrace das Canvas abspeichern. Danke!

Freundliche Grüsse
Milos
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:35 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