TBITMap to PNG?

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

TBITMap to PNG?

Beitrag von pluto »

Hallo,
habe heute versucht eine TBitMap Variable im PNG Format abzuspeichern.
Mit Hilfe der OpBitmap-Lib

Code: Alles auswählen

procedure TForm1.SaveScreenShot;
var
  sss:TBitMap;
  OpBMP:TOPBitmap;
  OoP:TOPPicture;
  oopC:TCanvasOPBitmap;
begin
  sss:=TBitMap.Create;
  sss.Width:=GameW;
  sss.Height:=GameH;
  BitBlt(sss.Canvas.Handle,0,0,GameW,GameH,buffer.canvas.Handle,gamex,gamey,SRCCOPY);
 
  OpBMP:=TOPBitmap.Create;
  oopC:=TCanvasOPBitmap.Create;
 
  AssignBitmapToOpBitmap(sss,opBMP);
  AssignOpBitmapToCanvas(opBMP,oopC.Canvas,0,0);
 
  oopC.SaveToFile(SaveToFile('/media/hda7/test1.png'));
//  OoP:=TOPPicture.Create;
  //oop.Bitmap.Canvas.Draw(0,0)
 
 // OoP.SaveToFile('/media/hda7/test1.png');
 
  sss.Free;
  OpBMP.Free; oop.Free;
end;
der geht leider nicht.....
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Stimmt Pluto. Das ist ein Bug der mir seltsamerweise noch nie untergekommen ist.

TOPPicture created sein OPBitmap in der jetzigen Version erst beim Laden eines Bildes. Das ist natürlich schlecht, wenn man darauf zugreifen will, ohne vorher was zu laden.

Der Fix ist ganz einfach:

in opbitmapformats.pas:

Mach dem TOPPicture einen Konstruktor und create ein beliebiges Format, z.B. TBmpImage. Es ist egal was, wird sowieso beim speichern angepasst.

Code: Alles auswählen

constructor TOPPicture.Create;
begin
  fCurrentFormat := TBmpImage.create;
end;
Das ist alles.

Dann klappt z.B. das hier:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var op:TOPPicture;
bmp:TBitmap;
begin
bmp:=TBitMap.Create;
bmp.Width:=100;
bmp.Height:=100;
bmp.Canvas.brush.Color:=clred;
bmp.Canvas.FillRect(0,0,100,100);
 
op:=TOpPicture.Create;
AssignBitmapToOpBitmap(bmp,op.Bitmap);
op.SaveToFile('/home/theo/test2.png');
op.free;
 
bmp.free;
end;
Merci für's finden des Fehlers ! ;-)

P.S. ist nun auch hier gefixt: http://www.theo.ch/lazarus/opbitmap1_6.zip" onclick="window.open(this.href);return false;
Für die paar Zeilen lohnt sich aber der download nicht.

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

VIELEN DANK !

Weil BMP sind auf dauer einfach zu groß..... Ich finde dein LIb gar nicht mal so schlecht, Nutze sie jetzt in zwei meiner Projekte beide werde ich evlt. hier hoch laden.

01: Ein Spiel was ich nach machen wollte, bestand aus sehr vielen PNG und BMP Dateien, dafür habe ich ein Programm geschrieben welche sie in einer einzigen Grafik Datei unterbringen kann. Im Moment nur BMP, aber das passe ich noch an.

02: Das Eigentliche Spiel: "Flos Draw Ball"
http://www.delphipraxis.net/topic97281_ ... +0806.html" onclick="window.open(this.href);return false;
(Auf der Letzen oder Vor Letzten seite habe ich auch ein ScreenShott gepostet)

Entwickelst du die LIb eigentlich noch weiter ?
Z.b. eine Imagelist währe doch gar nicht mal so schlecht oder ?
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

pluto hat geschrieben: Entwickelst du die LIb eigentlich noch weiter ?
Weiss nicht. Ist doch eigentlich fertig für das wass es sein soll, oder?
Vielleicht mache ich mal noch eine Sammlung von Bildbearbeitungsprozduren.
z.B. Floodfill, Rotieren, Weichzeichnen etc. Aber das ist ein Fass ohne Boden.
Für die Imagelist sehe ich jetzt nicht unbedingt einen Zweck, du kannst ja jederzeit das OpBitmap in ein TBitmap umwandeln und umgekehrt.
Was fehlt denn wirklich?

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Hab hier mal was zusammengestellt:
http://www.theo.ch/lazarus/opimglib.zip" onclick="window.open(this.href);return false;

Demos für:
Schärfen, Weichzeichnen, freies Rotieren, Floodfill und Farbe ersetzen.

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

> eine Sammlung von Bildbearbeitungsprozduren.
das wäre nicht schlecht ! Ja da gibt es viele, ich würde Licht Effekte Toll finden.... wenn du sowas einbauen könntest.... z.b. ein oder mehrer Scheinfer oder andere Lichtquellen die dann z.b. rote oder blaues licht abgeben in einem Bestimmten bereich.... währe das was für dich ?

> Was fehlt denn wirklich?
Im Moment sehe ich nichts außer halt paar Vereinfachung:
Z.b. bei den halb-Tranzparenten Rechtecken

Als Image list dachte ich z.b. sowas:
so wie die das bei SuperTux gelöst haben:
Eine Datei wo z.b. Informaitonen drin stehen, wo welche Grafik ist.

Und das dann halt mit OpBitmap sachen, ohne das man umwandeln muss... dann müsstem man nur noch einmal umwandeln und könnte evlt. Speicher und Aufwand sparen... wenn du mir folgen kannst.
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

pluto hat geschrieben:Ja da gibt es viele, ich würde Licht Effekte Toll finden.... wenn du sowas einbauen könntest.... z.b. ein oder mehrer Scheinfer oder andere Lichtquellen die dann z.b. rote oder blaues licht abgeben in einem Bestimmten bereich.... währe das was für dich ?
Wie gesagt, das ist ein Fass ohne Boden. Da könnte man 1000 Effekte basteln.
Ich schau mal, wenn ich Zeit hab. Oder du? ;-)
pluto hat geschrieben: Im Moment sehe ich nichts außer halt paar Vereinfachung:
Z.b. bei den halb-Tranzparenten Rechtecken
Was ist denn daran schwierig?
pluto hat geschrieben: Als Image list dachte ich z.b. sowas:
so wie die das bei SuperTux gelöst haben:
Eine Datei wo z.b. Informaitonen drin stehen, wo welche Grafik ist.

Und das dann halt mit OpBitmap sachen, ohne das man umwandeln muss... dann müsstem man nur noch einmal umwandeln und könnte evlt. Speicher und Aufwand sparen... wenn du mir folgen kannst.
Das sind anwendungspezifische Sachen. Die hast du schnell selber gemacht, so wie sie du haben möchtest. Ich glaube nicht, dass sowas in die Lib gehört.
Der Vorteil von OPBitmap dabei ist, dass es nur Speicher frisst und keine GDI Ressourcen.
Ausserdem belegt ein OPBitmap wirklich nur den Speicher, den es braucht.
Also z.B. bei einem 8 bit GIF nicht 32 bit pro Pixel.

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

> Was ist denn daran schwierig?
ist es auf ein kleiner Aufwand der vereinfacht werden könnte mehr nicht

Naja wobei schnell relativ ist... aber du hast recht... ich dachte halt nur als Erweiterung. Wenn es der User Braucht kann er es nutzen wenn nicht läst er es bleiben.... es würde halt passen, aber sowas kann ich evlt. mal versuchen einzubauen als Erweiterung....

Das mit den Effekten ist nicht schlecht, halt das Licht würde ich Interessant finden. Ob ich auch welche Einbaue weiß ich noch nicht.

Wobei Farbverläufe zählen doch auch dazu oder ?
Ich kann ja mal schauen was es für nette sachen da gibt...

Was ich noch als Effekt einbauen möchte sind Grafik(BMP, oder sonst was) Fonts. Das ist nicht besonders Schwierig(habe ich schonmal gemacht).

Aber Wirkungsvoll. Was meinst du dazu ?

Meine Grafik Font's würden aus zwei Dateien bestehen:
Einer Grafik Datei
Einer Text Datei, diese Text Datei enthält die genau Abildung wie die Schrift Art auch in der Grafik aussieht... und weil es ein Raster ist kann ich relativ leicht die Position Berechnen wo sie in der Grafik Datei liegt...

Dann müsste ich mir nur noch eine Eigene DrawText Funktion schreiben und Fertig.... Das könnten wir/ich als Addon dazu packen. Währe bestimmt nicht schlecht... Z.b. könnte daraus auch eine Komponente Werden, wenn es soweit ist.... Evlt. finde ich ja mal die Lust dazu sowas nochmal zu versuchen... ich brauche halt passende Grafiken erstmal.... Wo ich auch weiß wie groß die einzelne Zeichen sind....
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

pluto hat geschrieben:ist es auf ein kleiner Aufwand der vereinfacht werden könnte mehr nicht

Und wie?
pluto hat geschrieben: Was ich noch als Effekt einbauen möchte sind Grafik(BMP, oder sonst was) Fonts. Das ist nicht besonders Schwierig(habe ich schonmal gemacht).

Aber Wirkungsvoll. Was meinst du dazu ?
Wozu?

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

Naja einfach nur so, das es da ist..... Als optische Verbessrung z.b. könnte sowas in Info Dialoge zum Einsatz kommen oder in einfache 2D Spiele...
Und wie?

Code: Alles auswählen

procedure TForm1.CreateGameDisPlay;
var
  r:Trect;
  Hintergrund:TOPPicture;
  Pfeil:TOPPicture;
  ah:TCanvasOPBitmap;
begin
 Hintergrund:=TOPPicture.Create;
  Hintergrund.LoadFromFile(imagedir + 'display.png');
  DisPlay.Width:=100;
  DisPlay.Height:=100;
 
  ah:=TCanvasOPBitmap.Create;
  ah.AlphaBlend:=True;
  ah.Width:=Panel1.Width; ah.Height:=50;
  ah.Canvas.Brush.color:=clBlue;
  ah.canvas.FillRect(rect(0,0,100,display.Height));
  ah.SetAlpha(100);
 
  Hintergrund.Bitmap.Canvas.Draw(20, 0, ah);
 
 
  AssignOpBitmapToBitmap(Hintergrund.Bitmap,DisPlay);
  Hintergrund.free;
  ah.free;}
  DisPlayBackup:=TBitMap.Create;
  DisPlayBackup.Assign(Display);
end;
Ich finde nur das sind ein Paar Zeilen zu viel... und was ist wenn ich davon mehrer Haben möchte ?
Gut einige Zeile gehören nicht unbedingt dazu.
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Die meisten Zeilen gehören nicht direkt zum Alphablending.
eigentlich nur:
ah.AlphaBlend:=true; //gibt an, ob beim Kopieren/Zeichnen Alphablending werwendet wird
und
Hintergrund.Bitmap.Canvas.Draw(20, 0, ah); //Kopiert/Zeichnet das Bild.

Im Rest des Codes bastelst du ein zweites Bitmap, bei welchem du den Alphakanal veränderst:
ah.SetAlpha(100);

Ist das nicht einfach genug?

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

naja dann muss ich es ja auch noch sichtbar machen bzw. in eine BITMAP kopieren um es weiter verwenden zu können.

Im Prinzip hast du recht, ist es schon sehr einfach gemacht von dir.

Ich wollte z.b. einige mal das ich eine Funktion habe die ein Bereich in einer BItmap definiert und halt Transparent einfärbt und halt auch sichtbar macht z.b. auf ein Panel.... Aber aus irgendeinen Grund habe ich es nicht geschafft....
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

pluto hat geschrieben: Ich wollte z.b. einige mal das ich eine Funktion habe die ein Bereich in einer BItmap definiert und halt Transparent einfärbt und halt auch sichtbar macht z.b. auf ein Panel.... Aber aus irgendeinen Grund habe ich es nicht geschafft....
Wie meinst du das? Transparenz geht doch, oder?

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

Ja ! Geht Prima ! nur wollte ich z.b. eine Procedure schreiben:
AddTranzparent(arect:Trect; Tranzparent:Integer);

und das konnte ich nicht... aber lassen wir es.... evlt befasse ich mich damit nochmal dann kann ich das Problem posten oder ich lasse es sein.
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Naja, das geht nicht:
AddTranzparent(arect:Trect; Tranzparent:Integer);

Du musst zwischen Transparent und Alpha-Kanal unterscheiden.
Transparent ist immer EINE Farbe pro Bitmap, und diese ist voll transparent.

Alpha Werte sind pro Pixel und es sind Zwischenwerte möglich.
Du kannst aber nicht halb-transparent auf einem Widget zeichnen, das unterstützt GTK nicht.

Antworten