Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Ordentliche Komprimierungsunit (https://www.delphipraxis.net/138629-ordentliche-komprimierungsunit.html)

GreenHorn3600 13. Aug 2009 23:09


Ordentliche Komprimierungsunit
 
Hallo Wissende,

wollte mal fragen, ob jemand von euch eine ordentlche Komprimierungsunit hat, welche man sowohl in kommerziellen als auch in OS Projekten einsetzen darf.

Die ZLib funktioniert ja halbwegs, schafft schon mal 2°/oo an Komprimierung oder vergrössert gleich um 100% beim komprimieren ;-) . Wenn man dann die Datei mit einem HexEditor ansieht, sieht sie unverändert aus. Also scheint sie wohl nicht so das richtige zu sein.

Aber vielleicht kennt ja einer von euch, da was Sinnvolles :-)

Schöne Grüße
Greeny

Luckie 13. Aug 2009 23:23

Re: Ordentliche Komprimierungsunit
 
Zitat:

Zitat von GreenHorn3600
Die ZLib funktioniert ja halbwegs, schafft schon mal 2°/oo an Komprimierung oder vergrössert gleich um 100% beim komprimieren ;-) . Wenn man dann die Datei mit einem HexEditor ansieht, sieht sie unverändert aus. Also scheint sie wohl nicht so das richtige zu sein.

Kann ich mir eigentlich nicht vorstellen. Deswegen bin ichmir ziemlich sicher, dass du da irgendwas falsch machst.

GreenHorn3600 15. Aug 2009 23:23

Re: Ordentliche Komprimierungsunit
 
*push*

weiss keiner, wie man Streams ordentlich komprimieren kann? Wobei die Unit für Closed und OS geeignet sein sollte?

:stupid: :stupid: :stupid:

Luckie 15. Aug 2009 23:46

Re: Ordentliche Komprimierungsunit
 
ZLib.

Meinst du nicht auch, dass wenn sie der Maßen schlecht funktionieren würde, dass sich da nicht schon andere gemeldet hätten?

Du kannst jetzt entweder weiter nach einer Alternative suchen oder du zeigst uns mal deinen Code und wir suchen deinen Fehler.

GreenHorn3600 16. Aug 2009 00:12

Re: Ordentliche Komprimierungsunit
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo Luckie,

dann mal viel Spass beim Suchen :-) . Habe gerade ein kleines Testprojekt zusammengezimmert, sollte aber für einen Einblick genügen.

Edit: Update der Compremierungsroutine (Position := 0 vergessen)
Delphi-Quellcode:
procedure TForm2.Compress;
var
  zc: TZCompressionStream;
  ms1: TMemoryStream;
  buff: array [0..2048] of byte;
  len: integer;
begin
  ms1 := TMemoryStream.Create;
  try
   zc := TZCompressionStream.Create(ms1, zcMax);
   try
     ms.Position := 0;
     repeat
       len := ms.Read(buff, 2048);
       zc.Write(buff, len);
     until len <> 2048;
     lRateOfCompression.Caption := Format('%.3f', [zc.CompressionRate]);
     ms.Position := 0;
     ms.CopyFrom(ms1, ms1.Size);
   finally
      zc.free;
    end;
  finally
    ms1.Free;
  end;
end;
Grüße
das GreenHorn

Dax 16. Aug 2009 00:25

Re: Ordentliche Komprimierungsunit
 
Du musst den Zielstream (glaube ich) vor'm kopieren leeren, sonst behält der die alte Länge und wird höchstens länger.

jaenicke 16. Aug 2009 04:48

Re: Ordentliche Komprimierungsunit
 
Das ist so, ja. Leeren oder die Größe danach auf die neue Größe setzen. ;-)

GreenHorn3600 16. Aug 2009 09:01

Re: Ordentliche Komprimierungsunit
 
Hallo Dax, Jänicke,

mhhh, ist nicht wirklich hilfreich. Wie ihr mit einem Blick auf den Code erkennen könnt, wird der Ausgabestream neu (also leer) erzeugt. Er wird ja auch prima gefüllt. Nur, ist dann der Inhalt reichlich unkomprimiert... Dies war ja auch meine Kritik dran, daher die Frage nach einer anderen, welche es besser kann. Übrigens, ein kleines Beispielprojekt ist angehangen, nur die Methode ist gegen die aktuelle hier aus dem obigen Post zu tauschen.

Greeny

SirThornberry 16. Aug 2009 11:09

Re: Ordentliche Komprimierungsunit
 
Zitat:

Zitat von GreenHorn3600
...Wie ihr mit einem Blick auf den Code erkennen könnt, wird der Ausgabestream neu (also leer) erzeugt...

Ich sehe nur das der MemoryStream erzeugt wird.
Ansonsten liest du aus einem anderem Stream (ms) und schreibst diesen in cz/ms1.
Anschließend kopierst du den komprimierten Stream an den Anfang des Streams aus dem du die ganze Zeit gelesen hast.
Ist dein unkomprimierter Stream also z.B. 5 MB groß und die komprimierten Daten sind 1 MB groß, so schreibst du diese 1 MB an den anfang des Ursprüngsstreams. Die restlichen 4 MB des Ursprungsstreams bleiben allerdings erhalten so das deine Datei weiterhin 5 MB groß ist. Welchen Sinn macht das?
Zudem verstehe ich deine Vorgehensweise mit der Schleife nicht. Warum verwendest du an dieser Stelle nicht bereits die CopyFrom-Methode?

alzaimar 16. Aug 2009 11:35

Re: Ordentliche Komprimierungsunit
 
Hi Greeny,

Für dich dürfte es keine geeignete Kompressions-Unit geben. Du kannst nämlich mit egal welcher Klasse nicht richtig umgehen. :thumb:
Bei mir funktioniert ZLib ganz prächtig, aber ich weiss auch, wie man die Library verwenden muss. Der Hauptfehler befindet sich übrigens in 99% der Fälle ca. 80cm vom Bildschirm entfernt und zeigt mit dem Finger auf andere. :mrgreen:

Hier eine dezent korrigierte Version, sowie eine Alternative, die etwas kompakter ist, da sie den zu komprimierenden Stream einfach per CopyFrom direkt in ZLib reinbläst, anstatt sie in 2k-Happen zu komprimieren (Meine Unit kennt übrigens kein TZCompressionStream, vielleicht liegt es auch daran):
Delphi-Quellcode:
procedure TForm2.Compress;
var
  zc: TCompressionStream;
  ms1: TMemoryStream;
  buff: array[0..2048] of byte;
  len: integer;
begin
  ms1 := TMemoryStream.Create;
  ms.position := 0; // 1.Fehler, ms war am Ende und u.g. 'read' lieferte 0 bytes.
  try
    zc := TCompressionStream.Create(clMax, ms1);
    try
      repeat
        len := ms.Read(buff, 2048);
        zc.Write(buff, len);
      until len <> 2048;
      lRateOfCompression.Caption := Format('%.3f', [zc.CompressionRate]);
    finally
      zc.free; // 2.Fehler: Der ZCompressionStream hat noch Einiges im Puffer
    end;
    ms.clear; // 3.Fehler: Alten Stream löschen
    ms.CopyFrom(ms1, 0); // 4.Fehler: ms1 komplett von Anfang an kopieren
  finally
    ms1.Free;
  end;
end;

procedure TForm2.Compress1;
var
  zc: TCompressionStream;
  ms1: TMemoryStream;

begin
  ms1 := TMemoryStream.Create;
  try
    zc := TCompressionStream.Create(clMax, ms1);
    try
      zc.CopyFrom(ms, 0);
    finally
      zc.free;
    end;
    lRateOfCompression.Caption := Format('%.3f', [zc.CompressionRate]);
    ms.clear;
    ms.CopyFrom(ms1, 0);
  finally
    ms1.free;
  end;
end;
Bevor Du dich über meine Sticheleien echauffierst, bedenke, das Du dich sehr weit aus dem Fenster gelehnt hast und offenbar über eine gehörige Portion Selbstbewustsein verfügst, denn sonst würdest Du nicht allen Ernstes als 'GreenHorn' eine dermaßen erprobte Unit wie ZLib in Frage stellen. Soviel Chuzpe muss man erstmal haben :lol:

:cheers:


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:28 Uhr.
Seite 1 von 3  1 23      

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