Bilder schnell laden (OPBitmap)

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
Antworten
monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Bilder schnell laden (OPBitmap)

Beitrag von monta »

Mir viel kein besserer Titel ein ;)

Ich hab ein kleines Geschwindigkeitsproblem und vielleicht kennt jemand eine schnellere Möglichkeit.

Das Problem ist folgendes, ich lade 9 Bilder jeweils in TImage. Die Datei liegt als PNG vor.

Allerdings dauert das laden über Image.LoadFromFile doch recht lange. Nun hab ich gerade mit OpBitmap rumgespielt, allerdings hat das auch nichts gebracht, oder ich hab was falsch gemacht. Bei Bitmap-Dateien war OPBitmap ca. 25% schneller beim laden als das Standard-LoadFromFile. Bei PNG-Dateien sind beide allerdings ca. gleich schnell.
Bei OPBitmap hab ich folgendes verwendet:

Code: Alles auswählen

var fOP: TLazOPPicture;
//..
    fOP.LoadFromFile(Datei);
    fOP.DrawImage;
eventuell gibt es da auch besseres?

//Nachtrag:
ich hab mich doch für Bitmap entschieden, die Zeit zum dekomprimieren ist einfach verschenkt bei den anderen Formaten.
Aber wie läd man mit OpBitmap am schnellsten Bitmaps mit 8 oder 4Bit Palette bzw. warum ist 4Bit so signifikant langsamer als 8Bit und 8Bit sind immernoch langsamer als 24Bit.
Da muss es doch noch was zum einstllen geben, oder?
Ich würde ja sagen, bei 24Bit ist ja viel mehr zu verarbeiten, oder liegt es daran, das die 4/8Bit erstmal wieder auf 24-Bit hochgerechnet werden müssen?
Johannes

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

Re: Bilder schnell laden (OPBitmap)

Beitrag von theo »

Grundsätzlich ist nicht unbedingt anzunehmen, das die Decoder von OPBitmap schneller sind als die der LCL. (Kann sein, aber auch umgekehrt).
Testen!
monta hat geschrieben: eventuell gibt es da auch besseres?
Die einfachste Methode die Decoder/Encoder von OPBitmap zu verwenden ist "RegisterLazOp" in die Uses aufzunehmen.
Das es "wirkt" siehst du daran, dass dann der Standard Openpicturedialog diese als Filter anzeigt. (siehe lclintegrationdemo)
monta hat geschrieben: Ich würde ja sagen, bei 24Bit ist ja viel mehr zu verarbeiten, oder liegt es daran, das die 4/8Bit erstmal wieder auf 24-Bit hochgerechnet werden müssen?
Ja, umgerechnet muss immer werden. Selbst wenn es nicht über TLazInftImage sondern direkt ans Widgetset ginge.

Wenn du einen Batchconverter oder sowas bauen willst (also gar nie anzeigen auf dem Screen) kannst du das mit OpBitmap intern lösen.
Da entfällt mind. die Umrechnung für die Anzeige.

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Re: Bilder schnell laden (OPBitmap)

Beitrag von monta »

Ok danke.

Ich muss die Bilder schon anzeigen...genauer gesagt hab ich 9 Bilder 1000x1000 Pixel, die zu einem großen Quadrat zusammengesetzt werden und das Ergebnis ausgegeben.
Nun bin ich gerade am Basetln, was da am schnellsten geht, das allererste waren einfach 9 TImages und alle einzeln laden, nun setz ich es im Speicher zusammen und Lad dann das fertige große Bild in die Anzeige. Da die zusammensetzung der 9 Einzelteile sich aber ändern kann, muss das öfters gemacht werden, daher kommt es mir so auf die Geschwindigkeit beim verschieben an.

Seh ich das Richtig, wenn ich RegisterLazOp einbinde und dann ein ganz normales TBitmap erstelle, läuft das wie vorher über die LCL oder wird das damit auf OPBitmap 'umgeleitet'?
Johannes

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

Re: Bilder schnell laden (OPBitmap)

Beitrag von theo »

monta hat geschrieben: Ich muss die Bilder schon anzeigen...genauer gesagt hab ich 9 Bilder 1000x1000 Pixel, die zu einem großen Quadrat zusammengesetzt werden und das Ergebnis ausgegeben.
Ups, ganz schön fett 9000x9000 Pixel. Muss es so gross sein?
monta hat geschrieben: Nun bin ich gerade am Basetln, was da am schnellsten geht, das allererste waren einfach 9 TImages und alle einzeln laden, nun setz ich es im Speicher zusammen und Lad dann das fertige große Bild in die Anzeige. Da die zusammensetzung der 9 Einzelteile sich aber ändern kann, muss das öfters gemacht werden, daher kommt es mir so auf die Geschwindigkeit beim verschieben an.
Du kannst nat. versuchen, das ganze erstmal nur innerhalb von OpBitmap zusammenzusetzen (CopyRect) und erst am Schluss zum Zeichnen an die LCL übergeben.
monta hat geschrieben: Seh ich das Richtig, wenn ich RegisterLazOp einbinde und dann ein ganz normales TBitmap erstelle, läuft das wie vorher über die LCL oder wird das damit auf OPBitmap 'umgeleitet'?
Nein, ein TBitmap der LCL kann sowieso nur ein *.bmp und kein PNG laden. Erst ab TPicture werden die verschiedenen Formate geladen.

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Re: Bilder schnell laden (OPBitmap)

Beitrag von monta »

theo hat geschrieben:Ups, ganz schön fett 9000x9000 Pixel. Muss es so gross sein?
nicht ganz, 3x3, also 3000 x 3000 Pixel, ist aber trotzdem recht groß, viel kleiner geht aber nicht.
Das soll ganz einfach offline WMS-Daten anzeigen, die schon als 'Planquadrate' vorliegen.
theo hat geschrieben:Du kannst nat. versuchen, das ganze erstmal nur innerhalb von OpBitmap zusammenzusetzen (CopyRect) und erst am Schluss zum Zeichnen an die LCL übergeben.
Ok, werd ich mal probieren und anstatt TBitmap die OPBitmap-Entsprechung nehmen.
Johannes

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

Re: Bilder schnell laden (OPBitmap)

Beitrag von theo »

monta hat geschrieben: Ok, werd ich mal probieren und anstatt TBitmap die OPBitmap-Entsprechung nehmen.
Ich hab dir mal ne kleine Demo gemacht. Das musst du noch anpassen um die versch. Bilder zu laden.

Code: Alles auswählen

procedure TFrmLCLDemo.Button1Click(Sender: TObject);
var ResOP, TempOP:TOPPicture;
var i,j:integer;
var Rec1, Rec2:TRect;
begin
ResOP:=TOPPicture.create;
TempOP:=TOPPicture.create;
TempOP.LoadFromFile('/home/theo/mcbrain.png');
ResOp.Bitmap.Width:=TempOP.Bitmap.Width*3;
ResOp.Bitmap.Height:=TempOP.Bitmap.Height*3;
Rec1:=Rect(0,0,TempOP.Bitmap.Width,TempOP.Bitmap.Height);
For i:=0 to 2 do
 For j:=0 to 2 do
  begin
   Rec2:=Rec1;
   OffsetRect(Rec2,i*TempOP.Bitmap.Width,j*TempOP.Bitmap.Height);
   ResOp.Bitmap.Canvas.CopyRect(Rec2,TempOp.Bitmap.Canvas,Rec1);
  end;
AssignOpBitmapToBitmap(ResOp.Bitmap, Image1.Picture.bitmap);
ResOp.free;
TempOp.free;
end;

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Re: Bilder schnell laden (OPBitmap)

Beitrag von monta »

Besten Dank, ich bau das mal ein.
Johannes

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

Re: Bilder schnell laden (OPBitmap)

Beitrag von theo »

monta hat geschrieben:Besten Dank, ich bau das mal ein.
Optimieren für spezielle Fälle kann man natürlich immer irgendwie.
Da kommt es aber auf die Bedingungen an.
Wenn du die Bilder vor dem laden konvertieren kannst, wäre nat. ein (internes) obp Format sicher recht schnell wieder geladen. (u.U. Kompression abschalten in opbitmap.pas).
Eventuell die Bilder in einem extra Thread laden, damit's keine merkliche Verzögerung gibt.
Wenn nur Grauskala oder noch weniger gefragt ist, kann man auch Speicher sparen, mit 8bit oder 1bit.
Wenn du sowas hast musst du für das resultierende Bild eine Palette basteln. Am besten gleich alles auf fixe Palette (z.B. Websafe Colors oder Grayscale Palette) und dann Copyrect so anpassen, das es nur noch Bytes oder ganze Bildzeilen kopiert.
Für spezielle Bedürfnisse, könnte man die Daten von OpBitmap direkt ans Betriebssystem/Widgetset zum Zeichnen schicken, ohne erst über die LCL Grafik zu gehen. etc.
Alles eine Frage des Aufwands, den man betreiben will.

Antworten