Entwickler-Ecke

Dateizugriff - TMemoryStream komprimieren


g1o2k4 - Sa 12.09.09 15:12
Titel: TMemoryStream komprimieren
hallo.

ich habe analog zu einem zlib beispiel, die zlib einen memorystream komprimieren zu lassen, allerdings bekomme ich einen "Stream-LeseFehler".
der code bis jetzt:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var
  InputStream, OutputStream: TMemoryStream;
  CompressionStream: TZCompressionStream;
begin
  InputStream := TMemoryStream.Create;
  OutputStream := TMemoryStream.Create;
  Image1.Picture.Graphic.SaveToStream(InputStream);
  CompressionStream := TZCompressionStream.Create(OutputStream, zcFastest);
  CompressionStream.CopyFrom(InputStream, InputStream.Size); <---Fehler...!?
  CompressionStream.Free;
  InputStream.Free;


im outputstream soll also das komprimierte bild von image1 liegen und damit will ich weiter verfahren.
muss ich eine andere funktion benutzen um das bild als memorystream zu speichern?


alzaimar - Sa 12.09.09 16:24

Versuche Folgendes:

Delphi-Quelltext
1:
2:
...
  CompressionStream.CopyFrom(InputStream, 0); // Sonderfall: Kompletten Stream kopieren und vorher zurücksetzen


Ach, und den OutputStream sollte man auch noch freigeben...


g1o2k4 - Sa 12.09.09 16:35

user profile iconalzaimar hat folgendes geschrieben Zum zitierten Posting springen:

Ach, und den OutputStream sollte man auch noch freigeben...


jo klar hab ich nicht vergessen ^^ wie gesagt ich arbeite mit outputstream dann noch weiter.

edit: ich hab deinen vorschlag jetzt ausprobiert aber ich bekomme eine exception beim dekomprimieren:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
procedure TForm2.Button1Click(Sender: TObject);
var
  InputStream, OutputStream: TMemoryStream;
  DeCompressionStream: TZDecompressionStream;
  CompressionStream: TZCompressionStream;
  InputFileName, OutputFileName: string;
begin
  Image1.Canvas.Pixels[1,1] := clblack;


  InputStream := TMemoryStream.Create;
  Image1.Picture.Graphic.SaveToStream(inputstream);

  OutputStream := TMemoryStream.Create;
  CompressionStream := TZCompressionStream.Create(OutputStream, zcFastest);
  CompressionStream.CopyFrom(InputStream, 0);
  CompressionStream.Free;
  InputStream.Free;

  OutputStream.SaveToFile('.\test.jpg.bzip');

 // decompress
  Outputstream.Position := 0;
  InputStream := TMemoryStream.Create;
  Inputstream := Outputstream;
  Outputstream.Free;
  Outputstream := TMemoryStream.Create;
  DecompressionStream := TZDecompressionStream.Create(InputStream);
  OutputStream.CopyFrom(DecompressionStream, 0);
  Outputstream.SaveToFile('.\test2.jpg');
  DecompressionStream.Free;
  OutputStream.Free;
  InputStream.Free;

end;


das ist die gesamte testprozedur. ich kann jede anweisung ausführen aber am ende komm trotzdem eine exception die sagt "ungültige zeigeroperation". und die test2.jpg ist 0kb groß, das bzip archiv ist 4kb groß also das könnte bei ner fast weißen bitmap schon hinkommen.
aber wie dekomprimieren?


edit2: es geht, Inputstream := Outputstream; ist natürlich vollkommener blödsinn :P
also so geht es jetzt, für alle die es auch brauchen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
procedure TForm2.Button1Click(Sender: TObject);
var
  InputStream, OutputStream: TMemoryStream;
  DeCompressionStream: TZDecompressionStream;
  CompressionStream: TZCompressionStream;
  InputFileName, OutputFileName: string;
begin
  Image1.Canvas.Pixels[1,1] := clblack;


  InputStream := TMemoryStream.Create;
  Image1.Picture.Graphic.SaveToStream(inputstream);

  OutputStream := TMemoryStream.Create;
  CompressionStream := TZCompressionStream.Create(OutputStream, zcFastest);
  CompressionStream.CopyFrom(InputStream, 0);
  CompressionStream.Free;
  InputStream.Free;

  OutputStream.SaveToFile('.\test.jpg.bzip');

 // decompress
  Outputstream.Position := 0;
  InputStream := TMemoryStream.Create;
  Outputstream.SaveToStream(inputstream);
  Outputstream.Free;
  Outputstream := TMemoryStream.Create;
  DecompressionStream := TZDecompressionStream.Create(InputStream);
  OutputStream.CopyFrom(DecompressionStream, 0);
  Outputstream.SaveToFile('.\test2.jpg');
  DecompressionStream.Free;
  OutputStream.Free;
  InputStream.Free;

end;


jaenicke - So 13.09.09 08:49

Und hier nochmal ohne Speicherleck bei einem Fehler. Und ohne russisches Roulette mit dem Speicherpfad [http://www.delphi-library.de/viewtopic.php?p=499701], denn bei dir weißt du ja gar nicht, in welchem Pfad du das eigentlich speicherst.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
procedure TForm2.Button1Click(Sender: TObject);
var
  InputStream, OutputStream: TMemoryStream;
  DeCompressionStream: TZDecompressionStream;
  CompressionStream: TZCompressionStream;
  InputFileName, OutputFileName: string;
begin
  Image1.Canvas.Pixels[1,1] := clblack;


  OutputStream := TMemoryStream.Create;
  try
    InputStream := TMemoryStream.Create;
    try
      Image1.Picture.Graphic.SaveToStream(inputstream);

      CompressionStream := TZCompressionStream.Create(OutputStream, zcFastest);
      try
        CompressionStream.CopyFrom(InputStream, 0);
      finally
        CompressionStream.Free;
      end;
    finally    
      InputStream.Free;
    end;

    OutputStream.SaveToFile(ExtractFilePath(ParamStr(0)) + 'test.jpg.bzip');

 // decompress
    Outputstream.Position := 0;
    InputStream := TMemoryStream.Create;
    try
      Outputstream.SaveToStream(inputstream);
    
      Outputstream.Size := 0// Leeren reicht statt neu erzeugen auch
      DecompressionStream := TZDecompressionStream.Create(InputStream);
      try
        OutputStream.CopyFrom(DecompressionStream, 0);
        Outputstream.SaveToFile(ExtractFilePath(ParamStr(0)) + 'test2.jpg');
      finally
        DecompressionStream.Free;
      end;
    finally
      InputStream.Free;
    end;
  finally
    OutputStream.Free;
  end;
end;


g1o2k4 - So 13.09.09 10:28

danke werde ich umbauen, aber ich speichere das ganze nicht, das war nur zum debuggen um zu sehen ob was angekommt usw...