Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi JPEGfolge und TFileStream, "JPEG-Fehler #42" (https://www.delphipraxis.net/133111-jpegfolge-und-tfilestream-jpeg-fehler-42-a.html)

Te7Ris 25. Apr 2009 22:18


JPEGfolge und TFileStream, "JPEG-Fehler #42"
 
Hallo,

ich versuche eine Folge von JPEG-Bildern in einen FileStream zu speichern, um diese dann später wieder zu Laden und Anzuzeigen. Das erste Bild wird auch anstandslos geladen, doch sobald ich das zweite laden möchte bekomme ich den "JPEG-Fehler #42" und ich habe keine Ahnung wieso. Speicher ich die Bilder als BMP in den Stream, ist das spätere Laden und Anzeigen kein Problem.

Weiß jemand ob man vielleicht bei der mitgelieferten JPEG-unit die SaveToStream funktion, da nicht ganz sauber funktioniert und man mit stream.Write(..,..) weiter kommen würde? Oder kann mir jemand eine andere JPEG-unit empfehlen?

Gruß Maxi

Bernhard Geyer 25. Apr 2009 22:31

Re: JPEGfolge und TFileStream, "JPEG-Fehler #42"
 
Zeig mal deinen Quellcode?

Te7Ris 25. Apr 2009 22:42

Re: JPEGfolge und TFileStream, "JPEG-Fehler #42"
 
Hier werden die Bilder in den Filestream (jStream) gespeichert.
iStream ist ein TMemoryStrem, in dem bmp-Bilder stecken. Counter beinhaltet die anzahl der Bilder.

Delphi-Quellcode:
 jStream := TFileStream.Create('E:\AC.acl',fmCreate);
 iStream.Seek(0,soFromBeginning);

 for I := 0 to counter - 1 do
 begin
   tbmp := TBitmap.Create;
   tjpg := TJPEGImage.Create;
   tbmp.LoadFromStream(iStream);

   tjpg.CompressionQuality := 10;
   tjpg.Assign(tbmp);
   tjpg.SaveToStream(jStream);
   //tjpg.SaveToFile('E:\test\'+inttostr(i)+'.jpg');

   tbmp.Free;
   tjpg.Free;
 end;

 iStream.Free;
 jStream.Free;
und hier wieder ausgelesen... "Image" ist ein TImage
das jeweils darauffolgende Bild sollen durch erneutes aussführen der letzen 4 codezeilen angezeigt werden...

Delphi-Quellcode:
jStream := TFileStream.Create('E:\AC.acl', fmOpenRead);

tjpg := TJPEGImage.Create;
tjpg.LoadFromStream(jStream);

Image.Picture.Assign(tjpg);

tjpg.Free;

Gruß Maxi

igel457 25. Apr 2009 22:51

Re: JPEGfolge und TFileStream, "JPEG-Fehler #42"
 
Der Fehler passiert jedem, der versucht JPEGs Sequentiell aus Dateien zu laden. Problem: JPEGs beinhalten keine Informationen darüber, wann die Bilddaten zuende sind, bzw. die Delphi-Unit ignoriert diese.

Lösung:
Speichere die JPEGS zunächst in einen Memorystream. Schreibe dessen Größe in deinen Filestream. Speichere den Memorystream in den Filestream.

Bei Laden ließt du zunächst die Größe wieder aus und kopierst so viele Bytes aus dem Filestream in den Memorystream. Lade das JPEG aus dem Memorystream.

Te7Ris 25. Apr 2009 23:07

Re: JPEGfolge und TFileStream, "JPEG-Fehler #42"
 
Ich speichere jetzt hiermit den MemoryStream (jStream) in den Filestream (fStream) so wie im vorherigen Post beschrieben

Delphi-Quellcode:
 fstream := TFileStream.Create('E:\AC.acl',fmCreate);
 jStream.Seek(0,soFromBeginning);

 Len := jStream.Size;
 fstream.Write(Len, SizeOf(Len));
 jStream.SaveToStream(fStream);
und versuche so an das erste JPEG herran zukommen, was jedoch direkt mit dem JPEG-Fehler #42 scheitert...

Delphi-Quellcode:
fStream := TFileStream.Create('E:\AC.acl', fmOpenRead);
jStream := TMemoryStream.Create;

fStream.Read(len, SizeOf(Len));
fStream.Read(jStream,len);

tjpg := TJPEGImage.Create;
tjpg.LoadFromStream(jStream);
Das Speichern und Auslesen der MemoryStreamgröße funktioniert ohne Probleme... Habe ich etwas falsch gemacht, oder muss ich die einzelnen Bilder auch jeweils mit "stream".write in den Stream schreiben und die Länge jedes Bildes vor das eigentliche Bild in den Stream schreiben (Ausslesen entsprechend)?

Gruß Maxi

igel457 26. Apr 2009 17:33

Re: JPEGfolge und TFileStream, "JPEG-Fehler #42"
 
So sollte es funktionieren:

Delphi-Quellcode:
//Speichern
fs := TFileStream.Create('E:\AC.acl', fmCreate);

//Für jedes einzelne Bild
ms := TMemoryStream.Create;
jpg.SaveToStream(ms),
len := ms.Size;
fs.Write(fs, SizeOf(len));
ms.SaveToStream(fs);
ms.Free;


//Laden
fs := TFileStream.Create('E:\AC.acl', fmOpenRead);

//Für jedes Bild
fs.Read(len, SizeOf(len));
ms := TMemoryStream.Create;
ms.CopyFrom(fs, len);
ms.Position := 0;
jpg.LoadFromStream(ms);
ms.Free;

Te7Ris 26. Apr 2009 17:36

Re: JPEGfolge und TFileStream, "JPEG-Fehler #42"
 
ah okay. Das versuche ich gleich... is ja dämlich, dass man für jedes Bild einen eigenen stream braucht^.^ hoffe bei anderen Dtatenstrukturen reicht da einer für alle ;-)

edit:
Jop so funktioniert es ^^ Danke an alle und besonders an igel natürlich :)
Gruß Maxi


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