Einzelnen Beitrag anzeigen

Benmik

Registriert seit: 11. Apr 2009
543 Beiträge
 
Delphi 11 Alexandria
 
#25

AW: Objekte einer TObjectList direkt aus dem Speicher lesen / in ihn schreiben

  Alt 8. Jan 2016, 20:51
Die Implementierung von HolgerX' Idee hat nicht funktioniert und sie war mir ohnehin nicht so geheuer, weil ich nicht nachvollziehen konnte, warum sie überhaupt manchmal funktioniert.

Ich bin jetzt den Weg gegangen, einfach biHeight manuell negativ zu setzen, denn die Bitmap muss doch gar nicht gedreht, sondern es müssen nur die Scanlines in anderer Richtung ausgelesen werden. Das funktioniert prima. Dabei bin auch auch gleich Perlsaus Rat gefolgt, die Funktion in die Klasse zu verlegen.
Wird hier noch Verbesserungspotenzial gesehen (bis auf die Sünde, Umlaute zu verwenden)? Dieses doppelte "Free" zum Beispiel stört mich immer.

Zur Erläuterung der PosBiHeight: Die Größe des FileHeaders ist immer fix bei 14 Bytes. Beim nachfolgenden DIB header gibt es 7 Größen, aber alle fangen mit 3 x 4 Byte an. Die hartkodierte numerische Angabe erscheint mir sicherer als so etwas wie SizeOf(BitmapFileHeader) + SizeOf(InfoHeader.biSize) + SizeOf(InfoHeader.biWidth).
Delphi-Quellcode:
function TBilderListe.LeseVSBAusDatei(Dateiname: string): Boolean;
var BildNr,AnzDS:integer; Stream,VSBStream:TMemoryStream; VSBBmp:TBitMap; VSBHöhe:integer;
const PosBiHeight = 14 + 4 + 4;
begin
  Result := False;
  If not FileExists(Dateiname)
    then exit;
  Stream := TMemoryStream.Create;
  Try
    Stream.LoadFromFile(Dateiname);
  Except
    Stream.Free;
    exit;
  End;
  Stream.Position := 0;
  Stream.ReadData(AnzDS);
  If AnzDS <> BilderListe.Count
    then exit;
  VSBStream := TMemoryStream.Create;
  Try
    For BildNr := 0 to AnzDS - 1 do begin
      VSBBmp := TBitMap.Create;
      VSBBmp.LoadFromStream(Stream);
      VSBStream.Clear;
      VSBBmp.SaveToStream(VSBStream);
      VSBStream.Position := PosBiHeight;
      VSBStream.ReadData(VSBHöhe,SizeOf(VSBHöhe));
      VSBStream.Position := PosBiHeight;
      VSBStream.WriteData(-Abs(VSBHöhe));
      VSBStream.Position := 0;
      VSBBmp.LoadFromStream(VSBStream);
      Self[BildNr].VSB := VSBBmp;
    end;
    Stream.Free;
    VSBStream.Free;
  Except
    Stream.Free;
    VSBStream.Free;
    exit;
  End;
  Result := True;
end;
  Mit Zitat antworten Zitat