TBitmap als PNG speichern

Rund um die LCL und andere Komponenten
Antworten
Timm Thaler
Beiträge: 1044
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

TBitmap als PNG speichern

Beitrag von Timm Thaler »

Ich erzeuge ein TBitmap und zeige es auf einem TImage an. Funktioniert soweit.

Jetzt möchte ich den Inhalt des TBitmap als PNG speichern, anhand dieser Anleitung http://wiki.freepascal.org/Developing_with_Graphics#Converting_formats sollte das gehen.

Code: Alles auswählen

procedure Tgui.btnsaveClick(Sender : TObject);
var
  imgpng : TPortableNetworkGraphic;
begin
  imgpng := TPortableNetworkGraphic.Create();
  try
    bmpimg.SaveToFile('bild.bmp')// funktioniert
    imgpng.Assign(bmpimg);
    imgpng.SaveToFile('bild.png')// wird erzeugt, ist aber leer
  finally
    imgpng.Free();
  end;
end;


Das Abspeichern als BMP geht, das Speichern als PNG erzeugt zwar eine Datei, und diese wird auch mit der richtigen Größe angegeben, allerdings ist das Bild in der Vorschau und im Bildbetrachter leer.

Wie konvertiere ich das Bitmap richtig in PNG fürs Abspeichern?

Ich habe auch einige Beispiele für Delphi gefunden, aber die sind nicht übertragbar. Natürlich könnte ich auch einfach als BMP abspeichern und nachträglich konvertieren. Ich würde gern wissen wie es richtig gehen könnte.

wennerer
Beiträge: 152
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 19.3 Cinnamon, Lazarus 2.1.0, FPC 3.3.1 ,Lazarus Stable 2.0.6,
CPU-Target: x86_64

Re: TBitmap als PNG speichern

Beitrag von wennerer »

Hallo Timm Thaler,

ich mache es so:

Code: Alles auswählen

 
if (ext = '.png') then
    begin
     TempPng  := TPortableNetworkGraphic.Create;
     TempPng.Assign(bmp);
     TempPng.SaveToFile(pfad);
     TempPng.Free;
    end;
 


Funktioniert bei mir einwandfrei. Sehe zu dir nur den Unterschied bei Create ohne ().
Vielleicht hilft dir das weiter.
Gruß
Bernd

Timm Thaler
Beiträge: 1044
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: TBitmap als PNG speichern

Beitrag von Timm Thaler »

Also die Klammern machen keinen Unterschied. Ich denke, Create und Free sind Funktionsaufrufe ohne Argumente, und da kann man die leeren Klammern weglassen. Ich schreib die üblicherweise mit, um Funktionsaufrufe von Variablen unterscheiden zu können.

Ich vermute mal, es liegt am Alphachannel. Wenn ich ein Bild mit mehr Inhalt abspeichere, wird die erzeugte Datei auch merklich größer (33kB gegen 12kB, in dieser Größenordnung). Im Faststoneviewer wird sie schwarz angezeigt, im Gimp als transparent, in der Vorschau weiss. Es wird auch die richtige Pixelhöhe und Breite angezeigt und es hat 32bit Farbtiefe. Allerdings kann ich in Gimp auch auf den Farbebenen nichts sehen und Manipulation am Alphachannel bringt nichts.

Das Bitmap erzeuge ich mit:

Code: Alles auswählen

  bmpimg := TBitmap.Create();
  bmpimg .PixelFormat := pf32bit;
  bmpimg .SetSize(xs, ys);
  gui.img.Picture.Bitmap.Assign(bmpimg );
 

Timm Thaler
Beiträge: 1044
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: TBitmap als PNG speichern

Beitrag von Timm Thaler »

Ahh, es war der Alphachannel. Hab PixelFormat auf pf24bit gesetzt, das Bild wird im TImage wie bisher angezeigt und jetzt auch im PNG richtig abgespeichert.

Die saubere Lösung wäre sicher, PixelFormat auf pf32bit zu lassen und den Alphachannel zu ändern, aber da muss ich nochmal recherchieren, wie das geht.

Mathias
Beiträge: 4851
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: TBitmap als PNG speichern

Beitrag von Mathias »

das Bild wird im TImage wie bisher angezeigt

Wieso so kompliziert.

Code: Alles auswählen

Image1.Picture.SaveToFile('test.png')
Einfacher geht wes wohl kaum. :wink:
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Timm Thaler
Beiträge: 1044
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: TBitmap als PNG speichern

Beitrag von Timm Thaler »

Mathias hat geschrieben:Wieso so kompliziert.

Code: Alles auswählen

Image1.Picture.SaveToFile('test.png')
Einfacher geht wes wohl kaum. :wink:


Ja, geht, allerdings ist mein test.png dann 1.3MB groß und in Wirklichkeit ein Bitmap. Die SaveToFile Funktion interessiert sich nämlich nicht für die angegebene Dateiendung, wenn der Bildinhalt nicht vorher in ein TPortableNetworkGraphic gewandelt wird, speichert die das einfach als TBitmap ab.

Mathias
Beiträge: 4851
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: TBitmap als PNG speichern

Beitrag von Mathias »

Wen ich es so mache, habe ich eine echte PNG.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  pic: TPicture;
begin
  Image1.Picture.LoadFromFile('project1.ico');
 
  pic := TPicture.Create;
  pic.Bitmap.Assign(Image1.Picture.Bitmap);
  pic.SaveToFile('test.png');
 
  pic.Free;
end;
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Warf
Beiträge: 1424
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: MacOS | Win 10 | Linux
CPU-Target: x86_64
Wohnort: Aachen

Re: TBitmap als PNG speichern

Beitrag von Warf »

Timm Thaler hat geschrieben:Ja, geht, allerdings ist mein test.png dann 1.3MB groß und in Wirklichkeit ein Bitmap. Die SaveToFile Funktion interessiert sich nämlich nicht für die angegebene Dateiendung, wenn der Bildinhalt nicht vorher in ein TPortableNetworkGraphic gewandelt wird, speichert die das einfach als TBitmap ab.


Es sollte keine Bitmap sein, denn die SaveToFile Methode extrahiert die Extension und sucht sich dann die dazu registrierte TGraphic Typen (Alle TGraphic Typen sind in einer Liste zusammen mit ihrer Extension gespeichert). Unter Delphi musste man noch eine eigene Unit Includen um PNG zu registrieren, unter Lazarus ist PNG aber Teil der Graphics Unit sollte damit also immer eingetragen sein, weshalb das eigentlich immer funktionieren sollte.

Timm Thaler
Beiträge: 1044
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: TBitmap als PNG speichern

Beitrag von Timm Thaler »

Ah, ein Mißverständnis.

Ich habe es mit dem TBitmap versucht, auf welches ich zeichne. Das wird als Bitmap gespeichert. Geht aber nicht mit der Eigenschaft "Picture". Wenn ich dagegen das TImage speichere, auf welches das TBitmap "assigned" wurde, dann funktioniert das mit dem "Picture" und wird als PNG gespeichert.

Code: Alles auswählen

  bmpimg.SaveToFile('ibmp.png'); => wird 1MB groß
  gui.img.Picture.SaveToFile('ipng.png'); => wird einige kB groß
 

Antworten