Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Bilder aus Stream Laden (https://www.delphipraxis.net/145903-bilder-aus-stream-laden.html)

Pro_RJ 10. Jan 2010 16:43


Bilder aus Stream Laden
 
huhu,

ich arbeite mit der graphic32.
Ich habe die Bilder in einer Datenbank gespeichert.
Jetzt möchte ich die Bilder aus der Datenbank in einer TImage32 anzeigen lassen.Die klappt mit BMPs alles auch ganz ordentlich.Nur JPGs/JPEGs machen probleme(mit dennen hab ich es bis her nur gestetet :-) ).Ich speichere mir in der Datenbank in einem BLOB-Feld die Datei als Stream.Wenn ich jetzt das Bild aus der DB laden möchte bekomme ich die Fehlermeldung "Bitmap ist ungültig".
Darauf hin habe ich mir eine kleine TestProc geschrieben, in der man das Problem gut nachvollziehen kann.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
Var FS : TFileStream;
    FName : String;
begin
  FName := 'C:\Bild1.JPG';

  // Geht
  //============
  Image321.Bitmap.LoadFromFile(FName);

  // Geht nicht
  //============
  FS := TFileStream.Create(FName,fmOpenRead);
  Image321.Bitmap.LoadFromStream(FS);
  freeandnil(Fs);

end;
Zur erklärung: in FName steht der Dateipfad des Bildes. Dieser pfad ist absolut ok.
Wenn ich das Bild per " Image321.Bitmap.LoadFromFile(FName);"lade, wird das Bild richtig angezeigt.
Wenn ich das Bild per "Image321.Bitmap.LoadFromStream(FS);" lade kommt die Fehlermeldung.

Man könnte jetzt den Umweg machen, und den Stream erst in einer Temp-Datei zu speichern und dann diese wieder zu laden aber das würde ich nur sehr ungern machen, da
1. wieder Schreibrechte benötigt und zum
2. Das Speichern und laden unnötige zeit benötigt
3. möchte ich das laden der Bilder in mehrere Threads ausladen.

mfg Jens

Alter Mann 10. Jan 2010 17:26

Re: Bilder aus Stream Laden
 
Hi,

versuche es mal so:
Delphi-Quellcode:
procedure  TXXXX.ReadImage(aFieldName : String);
var
  BS : TStream;
  MS : TMemoryStream;
begin
  BS := Query.CreateBlobStream(Query.FieldByName(aFieldName), bmRead);
  BS.Seek(0, soFromBeginning);
  MS := TMemoryStream.Create;
  MS.CopyFrom(BS, BS.Size);
  MS.Position := 0;
  Image321.Bitmap.LoadFromStream(MS);
  MS.Free;
  BS.Free;
end;
Alter Mann

alleinherrscher 10. Jan 2010 17:31

Re: Bilder aus Stream Laden
 
Ich würde keine JPGs per bitmap.loadfromfile bzw. bitmap.loadfromstream laden, da es sich hier, wie der name schon vermuten lässt, eigentlich um Bitmaps handelt. Mag sein, dass Delphi so intelligent ist, und anhand der Dateiendung bei loadfromfile erkennt, dass es sich um ein jpg handelt.

Aber ich würde den umweg über ein TJPEGImage gehen, und zunächst das Bild per loadfromstream in das TJPEGImage laden. Anschließend würde ich dann die canvas auf das Bitmap kopieren. Das ist meiner Meinung nach der korrekte weg.

Grüße,
Michael

[edit]

Quasi so:
Delphi-Quellcode:
 
function JPEGtoBMP(FS:TFilestream):tbitmap;
var jpeg:tJPEGImage;
begin
 
 Jpeg:= TJPEGImage.Create;
  try
    jpeg.LoadFromStream(FS);
    result:= TBitmap.Create;
    result.Assign(jpeg);
  finally
    jpeg.Free
  end;

end;

Pro_RJ 10. Jan 2010 19:37

Re: Bilder aus Stream Laden
 
Danke für die schnellen Antworten:

Zitat:

Zitat von Alter Mann
Hi,

versuche es mal so:
Delphi-Quellcode:
procedure  TXXXX.ReadImage(aFieldName : String);
var
  BS : TStream;
  MS : TMemoryStream;
begin
  BS := Query.CreateBlobStream(Query.FieldByName(aFieldName), bmRead);
  BS.Seek(0, soFromBeginning);
  MS := TMemoryStream.Create;
  MS.CopyFrom(BS, BS.Size);
  MS.Position := 0;
  Image321.Bitmap.LoadFromStream(MS);
  MS.Free;
  BS.Free;
end;
Alter Mann

Das Ist ja im Prinzip das gleiche wie ich es auch habe, nur, das ich per TStream und nicht per TMemoryStream zugreife. --> ich habs gesetztet aber das ergebniss ist leider noch das gleiche :-(


Zitat:

Zitat von alleinherrscher
Ich würde keine JPGs per bitmap.loadfromfile bzw. bitmap.loadfromstream laden, da es sich hier, wie der name schon vermuten lässt, eigentlich um Bitmaps handelt. Mag sein, dass Delphi so intelligent ist, und anhand der Dateiendung bei loadfromfile erkennt, dass es sich um ein jpg handelt.

Aber ich würde den umweg über ein TJPEGImage gehen, und zunächst das Bild per loadfromstream in das TJPEGImage laden. Anschließend würde ich dann die canvas auf das Bitmap kopieren. Das ist meiner Meinung nach der korrekte weg.

Grüße,
Michael

[edit]

Quasi so:
Delphi-Quellcode:
 
function JPEGtoBMP(FS:TFilestream):tbitmap;
var jpeg:tJPEGImage;
begin
 
 Jpeg:= TJPEGImage.Create;
  try
    jpeg.LoadFromStream(FS);
    result:= TBitmap.Create;
    result.Assign(jpeg);
  finally
    jpeg.Free
  end;

end;


Das werde ich gleich mal Testen. Betrifft das JPG und JPEG? :gruebel:

-=Breeze=- 10. Jan 2010 20:25

Re: Bilder aus Stream Laden
 
jpg = jpeg ;)

Früher waren die Dateiendungen auf 3 Buchstaben begrenzt

Pro_RJ 10. Jan 2010 21:35

Re: Bilder aus Stream Laden
 
Ahh wieder was gelernt :-D :-D :-D

also ich habs jetzt mal getestet. Das scheint soweit auch zu klappen :thumb: :thumb:
Nur dabei ist mir ein problem aufgefallen, Dass das Laden von ca 10 JPGs mit ca 4-5 MB größe in eine "TBitmap32List" erzeugt fast 700MB!!! Speicherauslastung, die auch gehalten werden.Kann es sein, das Intern die Jpgs in BMPs umgewandelt werden?
Ich glaub, ich muss doch mal nach einer anderen komponente suchen, und die Bilder anzuzeigen.


Danke für die rasche hilfe :-)

alleinherrscher 10. Jan 2010 22:11

Re: Bilder aus Stream Laden
 
Zitat:

Zitat von Pro_RJ
Kann es sein, das Intern die Jpgs in BMPs umgewandelt werden?

Schau mal wie die Funktion heißt: JPGTOBMP ;-) Das sollte deine Frage beantworten. Eine Imagelist ist auch nicht unbedingt dafür da, 10 Fotos in Postergröße im Speicher zu halten. Aber wenn du doch eh mit ner Datenbank arbeitest, kannst du doch immer das Bild laden, was du gerade benötigst.

Pro_RJ 11. Jan 2010 10:16

Re: Bilder aus Stream Laden
 
Ich dachte, das mit dem

Delphi-Quellcode:
    jpeg.LoadFromStream(FS);
    result:= TBitmap.Create;
    result.Assign(jpeg)
der Stream als JPG geladen wird und das in dem Object "TBitmap.Create" nur dargestellt wird und nicht nochmal konvertiert wird.
Ich wollte es in einer IMGListe machen, da ich nur noch die Bilder anzeigen möchte also z.B. 3 Bilder nebeneinander und 5 Reihen untereinander also 3*5 Bilder.
(In etwar wie es im windows bei "Miniatur-Ansicht" gemacht wird. und nicht nur das eine Bild zu einem bestimmten Datensatz.
Und um dabei ständiges nachladen zu vermeiden, wollte ich die Bilder einmal laden und dann nur noch anzeigen.

alleinherrscher 11. Jan 2010 11:59

Re: Bilder aus Stream Laden
 
Hm, also das sollte kein Problem sein, 5 Bilder nebeneinander anzuzeigen. Aber evtl musst du sie dann beim Laden verkleinern (also nicht nur Strech auf True, weil das die Originalgröße im Speicher hält).

Du musst eine Sache bedenken: Wenn ein Bild in einem Programm angezeigt wird, müssen die Rohdaten des Bildes (also quasi die Bit-Map) vorliegen, weil der PC, Grafikkarte etc. ja wissen muss, welches Pixel auf dem Monitor in welcher Farbe dargestellt werden soll. Ein JPEG ist aber mit verschiedenen Mechanismen dateigrößen-optimiert. Das bedeutet unter anderem, dass es auf der Festplatte oder in der Datenbank oder wo auch immer komprimiert vorliegt. Es muss also (egal womit du ein JPEG anzeigen willst) erst dekomprimiert werden, bevor es angezeigt werden kann.

LG


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:49 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