großes Bitmap aus Speicher in TImage zeigen
-
- Beiträge: 244
- Registriert: Do 21. Jan 2010, 22:33
- OS, Lazarus, FPC: Windows Vista (L 0.9.31 FPC 2.5.1)
- CPU-Target: 32Bit
- Wohnort: z.z. Brasilien, sonst 82335 Berg-Leoni (südlich von München)
großes Bitmap aus Speicher in TImage zeigen
Hallo,
ich glaube, dieses Thema wurde schon einmal angesprochen. Ich habe eine große Bitmap (bmp, 24 oder 8 bpp, also schon pixelweise abgespeichert) im Speicher liegen und möchte die (bzw Ausschnitte daraus) auf einer TImage darstellen.
Kann ich da mit Stretchdraw arbeiten? Aber dazu bräuchte ich eine TGraphic, und die habe ich nicht.
Ich mache es jetzt mit der Opensource-Unit FreeImage.
Und dann die (skalierte) Bitmap im Speicher (mit derselben Größe wie die TImage) Zeile für Zeile via TLazIntfImage in die TImage kopieren.
Es funktioniert, dauert aber recht lange. Weiß jemand eine schnellere Lösung?
Ginge das ganze es auch mit OpenGl (und wäre das dann schneller?), und wie müßte man dann da vorgehen?
Herzlichen Dank!
P. Nikolaus
ich glaube, dieses Thema wurde schon einmal angesprochen. Ich habe eine große Bitmap (bmp, 24 oder 8 bpp, also schon pixelweise abgespeichert) im Speicher liegen und möchte die (bzw Ausschnitte daraus) auf einer TImage darstellen.
Kann ich da mit Stretchdraw arbeiten? Aber dazu bräuchte ich eine TGraphic, und die habe ich nicht.
Ich mache es jetzt mit der Opensource-Unit FreeImage.
Und dann die (skalierte) Bitmap im Speicher (mit derselben Größe wie die TImage) Zeile für Zeile via TLazIntfImage in die TImage kopieren.
Es funktioniert, dauert aber recht lange. Weiß jemand eine schnellere Lösung?
Ginge das ganze es auch mit OpenGl (und wäre das dann schneller?), und wie müßte man dann da vorgehen?
Herzlichen Dank!
P. Nikolaus
Re: großes Bitmap aus Speicher in TImage zeigen
Ein TBitmap ist eine TGraphic, wie man u.a. aus der Dokumentation ersehen kann.br_klaus hat geschrieben: Kann ich da mit Stretchdraw arbeiten? Aber dazu bräuchte ich eine TGraphic, und die habe ich nicht.
http://lazarus-ccr.sourceforge.net/docs ... itmap.html" onclick="window.open(this.href);return false;
Also StretchDraw oder CopyRect verwenden.
-
- Beiträge: 244
- Registriert: Do 21. Jan 2010, 22:33
- OS, Lazarus, FPC: Windows Vista (L 0.9.31 FPC 2.5.1)
- CPU-Target: 32Bit
- Wohnort: z.z. Brasilien, sonst 82335 Berg-Leoni (südlich von München)
Re: großes Bitmap aus Speicher in TImage zeigen
Lieber Theo.
Ich habe leider kein TBitmap (als Klasse), sondern nur die Bitmap des Bildes als solche (d.h. die einzelnen Pixel) und den dazugehörigen BitmapInfoHeader.
FreeImage liefert als Ergebnis einen Pointer, ein PFIBITMAP auf eine interne Datenstruktur, die die Bitmap und alle zugehörigen Parameter enthält, aber keine TBitmap.
Bei 24 bpp wird mit 32 bit Boundary abgespeichert (d.h. width mod 4 FüllBytes).
Wenn ich zB habe
Wie kann ich da jetzt die TBitmap bzw TGraphic mit den entsprechenden Daten beschicken, sodaß ich dann aufrufen kann
bzw.
Und bei StretchDraw, gibt es da keine Probleme mit der Art der Abspeicherung in FreeImage (32 bit Boundary)?
Herzlichen Dank
P. Nikolaus
Ich habe leider kein TBitmap (als Klasse), sondern nur die Bitmap des Bildes als solche (d.h. die einzelnen Pixel) und den dazugehörigen BitmapInfoHeader.
FreeImage liefert als Ergebnis einen Pointer, ein PFIBITMAP auf eine interne Datenstruktur, die die Bitmap und alle zugehörigen Parameter enthält, aber keine TBitmap.
Bei 24 bpp wird mit 32 bit Boundary abgespeichert (d.h. width mod 4 FüllBytes).
Wenn ich zB habe
Code: Alles auswählen
Procedure TForm1.Dib_to_Image(dib:PFIBITMAP);
var data:Pbyte;
bmi:PBITMAPINFOHEADER;
bmp: TBitmap // oder TGraphic?
w,h,bpp:integer;
r:TRect;
begin
data:= FreeImage_GetBits(dib); bmi:=FreeImage_GetInfo(dib);
w:=FreeImage_Getwidth(dib); h:=FreeImage_GetHeight(dib); bpp:=FreeImage_GetBpp(dib);
bmp := TBitmap.create; // oder TGraphic.create?
r:=image1.BoundsRect;
....
end;
Code: Alles auswählen
Image1.Canvas.Draw(0,0,bmp)
Code: Alles auswählen
image1.canvas.stretchdraw(r,bmp)
Herzlichen Dank
P. Nikolaus
Re: großes Bitmap aus Speicher in TImage zeigen
Wozu benutzt du FreeImage?
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: großes Bitmap aus Speicher in TImage zeigen
Das schein irgendeine uns unbekannt Bibliothek zu sein, deren Ursprung wir nicht kennen.theo hat geschrieben:Wozu benutzt du FreeImage?
Schau dir mal http://de.wikipedia.org/wiki/Windows_Bitmap" onclick="window.open(this.href);return false; an; Vielleicht kannst du dein Bitmap selbst (oder über deine Bibliothek) in einen TMemoryStream speichern und von dort wieder mit TBitmap lesen.br_klaus hat geschrieben:Ich habe leider kein TBitmap (als Klasse), sondern nur die Bitmap des Bildes als solche (d.h. die einzelnen Pixel) und den dazugehörigen BitmapInfoHeader.
FreeImage liefert als Ergebnis einen Pointer, ein PFIBITMAP auf eine interne Datenstruktur, die die Bitmap und alle zugehörigen Parameter enthält, aber keine TBitmap.
Bei 24 bpp wird mit 32 bit Boundary abgespeichert (d.h. width mod 4 FüllBytes).
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
-
- Beiträge: 244
- Registriert: Do 21. Jan 2010, 22:33
- OS, Lazarus, FPC: Windows Vista (L 0.9.31 FPC 2.5.1)
- CPU-Target: 32Bit
- Wohnort: z.z. Brasilien, sonst 82335 Berg-Leoni (südlich von München)
Re: großes Bitmap aus Speicher in TImage zeigen
FreeImage ist OpenSource (http://freeimage.sourceforge.net/download.html" onclick="window.open(this.href);return false;). Ich benütze es v.a., um jedes beliebige Bildformat laden zu können. FreeImage unterstützt fast alle existierenden Formate.
Und es ist sehr schnell.
Eine Möglichkeit, die ich gefunden habe, ist, die Daten auf der Disk zwischenzuspeichern und dann mit LoadFromFile in die Image zu laden.
Gibt es denn keine Möglichkeit, anstatt auf Disk, in den Zwischenspeicher (Clipboard) zu kopieren und dann vom Clipboard aus zu laden?
Und es ist sehr schnell.
Eine Möglichkeit, die ich gefunden habe, ist, die Daten auf der Disk zwischenzuspeichern und dann mit LoadFromFile in die Image zu laden.
Gibt es denn keine Möglichkeit, anstatt auf Disk, in den Zwischenspeicher (Clipboard) zu kopieren und dann vom Clipboard aus zu laden?
Re: großes Bitmap aus Speicher in TImage zeigen
In meinem OpBitmap gibt es in der Unit imagelibs/lazbridge32.pas im Bereich {$ifdef LCLWin32} bei OpBitmapPaint32 Code um DIB auf den Canvas zu bringen (unter Windows mit Pixelformat 32bit).
Vielleicht kannst du dich daran orientieren.
http://www.theo.ch/lazarus/opbitmap64.zip" onclick="window.open(this.href);return false;
Vielleicht kannst du dich daran orientieren.
http://www.theo.ch/lazarus/opbitmap64.zip" onclick="window.open(this.href);return false;
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: großes Bitmap aus Speicher in TImage zeigen
Es kommt darauf an, wie du die Daten abspeicherst. Clipboard ist in der Regel zu kompliziert; viel einfacher ist ein TMemoryStream (siehe meinen Beitrag oben).br_klaus hat geschrieben:Eine Möglichkeit, die ich gefunden habe, ist, die Daten auf der Disk zwischenzuspeichern und dann mit LoadFromFile in die Image zu laden.
Gibt es denn keine Möglichkeit, anstatt auf Disk, in den Zwischenspeicher (Clipboard) zu kopieren und dann vom Clipboard aus zu laden?
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
-
- Beiträge: 244
- Registriert: Do 21. Jan 2010, 22:33
- OS, Lazarus, FPC: Windows Vista (L 0.9.31 FPC 2.5.1)
- CPU-Target: 32Bit
- Wohnort: z.z. Brasilien, sonst 82335 Berg-Leoni (südlich von München)
Re: großes Bitmap aus Speicher in TImage zeigen
Mit Streams kenne ich mich leider gar nicht aus. Da gibt es so viele verschiedene Arten.
Welchen soll man hier verwenden?
Und wie müßte ich da vorgehen, um
a) die Daten in den Stream zu laden
b) sie zum Image zu schicken?
Herzlicen Dank
P. Nikolaus
Welchen soll man hier verwenden?
Und wie müßte ich da vorgehen, um
a) die Daten in den Stream zu laden
b) sie zum Image zu schicken?
Herzlicen Dank
P. Nikolaus
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: großes Bitmap aus Speicher in TImage zeigen
TStream ist eine allgemeine Klasse um Daten zu streamen, was soviel bedeutet, dass die Daten einfach irgendwohin gesendet oder von irgendwo gelesen werden. Je nach Quelle oder Ziel gibt es verschiedene, von TStream abgeleitete Klassen -- z.B. TFileStream für Dateien von der Festplatte, TMemoryStream für den Arbeitsspeicher (automatische Verwaltung des Speichers), bei Netzwerk-Komponenten usw.
Das kann ich dir nicht wirklich sagen, da das auch zu einem großen Teil von der Bibliothek (FreeImage) abhängt, die du verwendest. Allgemein gesehen, geht das so:br_klaus hat geschrieben:a) die Daten in den Stream zu laden
Code: Alles auswählen
var
s: TMemoryStream;
begin
s := TMemoryStream.Create;
s.Write(Buffer, Count); // Count Bytes aus Buffer in den Stream schreiben
end;
Dazu nimmst du den Stream von oben:br_klaus hat geschrieben:b) sie zum Image zu schicken?
Code: Alles auswählen
var
s: TMemoryStream;
begin
s.Position := 0; // die Position auf den Anfang setzen, damit alle Daten gelesen werden.
Image1.LoadFromStream(s); // hier werden die Daten gelesen
s.Free; // nicht vergessen, alles wieder freizugeben
end;
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
-
- Beiträge: 244
- Registriert: Do 21. Jan 2010, 22:33
- OS, Lazarus, FPC: Windows Vista (L 0.9.31 FPC 2.5.1)
- CPU-Target: 32Bit
- Wohnort: z.z. Brasilien, sonst 82335 Berg-Leoni (südlich von München)
Re: großes Bitmap aus Speicher in TImage zeigen
Die Daten aus der Bitmap, die da gelesen werden, sind das nur die Daten der Pixel oder auch der zugehörige Rumpf (BitmapInfoHeader, evtl. auch die Paletten)?
Und werden die Pixel in der Bitmap ohne FüllBytes gespeichert oder mit (wenn 32 Bit Boundary, wie in FreeImage)? Denn dann könnte ich ganz leicht zuerst einen BimapinfoHeader mit den entsprechenden Werten vom Stream lesen lassen und dann die Pixel, und dies dann in die Image vom Stream laden.
Wozu braucht man eigentlich überhaupt einen Stream? Man könnte doch genausogut direkt von einem Speicherort zum anderen Kopieren mit Move(src,dst,size) bzw CopyMem(dst,src,size) oder via Assembler (Intel: Rep Mov)? Was ist da der Unterschied zum Streamen?
Und werden die Pixel in der Bitmap ohne FüllBytes gespeichert oder mit (wenn 32 Bit Boundary, wie in FreeImage)? Denn dann könnte ich ganz leicht zuerst einen BimapinfoHeader mit den entsprechenden Werten vom Stream lesen lassen und dann die Pixel, und dies dann in die Image vom Stream laden.
Wozu braucht man eigentlich überhaupt einen Stream? Man könnte doch genausogut direkt von einem Speicherort zum anderen Kopieren mit Move(src,dst,size) bzw CopyMem(dst,src,size) oder via Assembler (Intel: Rep Mov)? Was ist da der Unterschied zum Streamen?
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: großes Bitmap aus Speicher in TImage zeigen
Die Frage ist nicht, was gespeichert wird, sondern was TBitmap lesen kann? Das musst du ausprobieren, oder im Quelltext nachlesen oder jemanden hier fragen, der sich mehr mit Grafiken beschäftigt als ich. In jedem Fall musst du aber das gesamte Bitmap im Stream ablegen (inkl. header, Paletten wenn vorhanden und natürlich die Bilddaten selbst).br_klaus hat geschrieben:Die Daten aus der Bitmap, die da gelesen werden, sind das nur die Daten der Pixel oder auch der zugehörige Rumpf (BitmapInfoHeader, evtl. auch die Paletten)?
Und werden die Pixel in der Bitmap ohne FüllBytes gespeichert oder mit (wenn 32 Bit Boundary, wie in FreeImage)? Denn dann könnte ich ganz leicht zuerst einen BimapinfoHeader mit den entsprechenden Werten vom Stream lesen lassen und dann die Pixel, und dies dann in die Image vom Stream laden.
Damit es einfacher geht. Wenn du nur im Arbeitsspeicher arbeitest, kannst du die von dir genannten Funktionen selbstverständlich verwenden, aber dann musst du dich auch um den Speicher kümmern. TMemoryStream kann dir das abnehmen. Außerdem kannst du mit TStream als Basisklasse mit einheitlichen Methoden Daten von verschiedenen Quellen lesen (siehe bspw. TBitmap.LoadFromStream und TBitmap.LoadFromFile).br_klaus hat geschrieben:Wozu braucht man eigentlich überhaupt einen Stream? Man könnte doch genausogut direkt von einem Speicherort zum anderen Kopieren mit Move(src,dst,size) bzw CopyMem(dst,src,size) oder via Assembler (Intel: Rep Mov)? Was ist da der Unterschied zum Streamen?
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein