![]() |
AW: Objekte einer TObjectList direkt aus dem Speicher lesen / in ihn schreiben
Hmm..
Anscheinend wird bei dem Bitmap, welches per ExtractThumbnail geholt wird etwas bei SaveToStream anders gemacht, wie bei Draw.. Wenn Du zunächst das Thumbnail mit einem 2. Bitmap holts und es dann auf dein eigentliches Bitmap malst (.Draw) dann gehts..
Delphi-Quellcode:
So ist dann das Bitmap in bmp mit der korrekten Orientierung.// Thumbnail aus JPG-Datei Bmp := TBitmap.Create; Bmp2:= TBitmap.Create; try ExtractThumbnail(Bmp2,Verz + JPGDatei,400,0); // Auf Form zeichnen Self.Canvas.Draw(450,10,Bmp2); Bmp.Assign(bmp2); Bmp.Canvas.Draw(0,0,bmp); .. finally Bmp2.Free; Bmp.Free; end; |
AW: Objekte einer TObjectList direkt aus dem Speicher lesen / in ihn schreiben
Zitat:
Delphi-Quellcode:
zu tun. Ein simples
SaveToStream
Delphi-Quellcode:
, was lediglich ein neues GDI-Objekt forciert, zeigt schon den Fehler. Vielleicht hat man den verlinkten Bug in der Implementation des IExtractImage Interfaces nicht mit gefixt.
bmp.Dormant
|
AW: Objekte einer TObjectList direkt aus dem Speicher lesen / in ihn schreiben
Zitat:
|
AW: Objekte einer TObjectList direkt aus dem Speicher lesen / in ihn schreiben
Danke an euch alle. Ich bin natürlich froh, dass ich jetzt nicht als Depp dastehe.
Die Lösung von HolgerX ist ziemlich schräg, funktioniert aber (und warum?). Das doppelte Zeichnen ist unter Umständen verschmerzbar, weil ja nur die sichtbaren Vorschaubilder gezeichnet werden, das ist überschaubar. Übrigens war es bei mir so, dass nicht immer alle Bilder auf dem Kopf standen, sondern nur die Hochkantbilder, während die querkantigen richtig herum waren. Ich werde mal sehen, ob HolgerX' Lösung auch hier wirkt. @Perlsau: Danke für deine Mühe. Ich möchte natürlich alle Bilder in einer einzigen Datei speichern. Das könnte ich natürlich auch in die Klasse der Objectlist integrieren. Der direkte Speicherzugriff war ja doch nur wegen der Rotationsproblematik. |
AW: Objekte einer TObjectList direkt aus dem Speicher lesen / in ihn schreiben
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; |
AW: Objekte einer TObjectList direkt aus dem Speicher lesen / in ihn schreiben
Dann schau dir mal
Delphi-Quellcode:
an, denn dafür ist das da.
try finally
|
AW: Objekte einer TObjectList direkt aus dem Speicher lesen / in ihn schreiben
Ja. Nur dass dann bei einer Exception der Code durchläuft und Result damit True ist.
Ich habe jetzt zu einem Sprunglabel gegriffen. Bei dem "exit" da oben kommt es ja auch zu einem Speicherleck. |
AW: Objekte einer TObjectList direkt aus dem Speicher lesen / in ihn schreiben
|
AW: Objekte einer TObjectList direkt aus dem Speicher lesen / in ihn schreiben
Zitat:
Delphi-Quellcode:
Wenn das Laden der Datei in den Stream schiefläuft, bleibt Result = False und somit wird die Methode nach dem Try-Finally-Block mit Exit verlassen. Normalerweise kann hier nichts schieflaufen, da ja die Existenz der Datei zuvor abgefragt wird. Einzige Fehlerquelle, die mir jetzt noch einfällt: Die Datei ist zu groß für den verfügbaren Arbeitsspeicher. Ich verwende daher immer noch einen Try-Except-Block innerhalb des Try-Finally-Blocks, um die Fehlermeldung zu erhalten, die in eine globale Fehlervariable geschrieben wird. Aber das kannst du letztendlich halten, wie du willst ...
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); Result := True; Finally Stream.Free; End; If Not Result Then Exit; ... |
AW: Objekte einer TObjectList direkt aus dem Speicher lesen / in ihn schreiben
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:15 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz