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;