![]() |
Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher?
Hallo!
Ich programmiere grad ein FotoShow-Programm, das mit Hilfe eine Threads die Thumbnails erstellt. Dabei kann man in einer Liste scrollen, und sehen, wo das Programm grad ist mit den Thumbs. Das klappt auch ganz gut, nur bei 100 Bildern sind sporadisch 1-2 dabei die er nicht anzeigt, weiß bleiben. Als Routine nehme ich Canvas.StretchDraw(..). Auch StretchBlt zeigt neben reduzierter Farbtiefe dieses Verhalten. Nehme ich dagegen Canvas.Draw, sind alle Bilder da und zeigen einen Ausschnitt vom Bild (Sinnigerweise nicht das ganze). Mir scheint, dass die Stretch-Befehle nicht Thread-sicher sind. Habt ihr Ideen? |
Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher
Hallo,
Eine brauchbare Qualität erreichst du mit StretchBlt indem du vorher den StretchBlt-Modus setzt:
Delphi-Quellcode:
Zur Threadsicherheit dieser Funktionen kann ich dir leider nichts sagen.
SetStretchBltMode(Canvas.Handle, STRETCH_HALFTONE);
SetBrushOrgEx(Canvas.Handle, 0, 0, nil); Könnte evtl. nicht eher das Problem sein, dass deine Threads irgendwas auf die Oberfläche pinseln? grüße, daniel |
Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher
Threadsicher wirst du das ganze selbst machen müssen. Also die Thumbs im Thread erzeugen und dann um das Thumb anzuzeigen (die Anzeigekomponente gehört ja dann zum Hauptthread) musst du wohl mit Syncronize arbeiten.
Also Thumb in Thread erzeugen -> Bild syncron mit Hauptthread zuweisen |
Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher
Zitat:
Die Qualität ist mit StretchBlt und
Delphi-Quellcode:
wesentlich besser als mit StretchDraw!
SetStretchBltMode(Canvas.Handle, STRETCH_HALFTONE);
SetBrushOrgEx(Canvas.Handle, 0, 0, nil); |
Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher
Hallo nochmal! Leider konnte ich keine Möglichkeit finden, die beiden genannten Prozeduren threadsicher zu machen. Selbst die Kapselung in dem Thread, der Schutz vor Zugriffen durch ein extra-Array (erst erstellen, dann ins Hauptprogramm kopieren) hat nichts gebracht. Mir ist aufgefallen dass StretchBlt hier mehr Aussetzer hat als StretchDraw.
Ich suche nach einer alternativen Prozedur oder Funktion, die Bilder verkleinert zeichen kann. Ich überlege grade, die G32-Lib zu benutzen, möchte aber eigentlich auf Fremdkomponenten verzichten. Wer weiß Rat? |
Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher
@axelf98: Wie hast du das ganze umgesetzt? Arbeitest du mit der Delphiklasse TThread?
auf folgende Art und weise sollte es eigentlich ohne Probleme möglich sein
Delphi-Quellcode:
type
TMyThead = class(TThread) private procedure MethodForSync; protected procedure Execute; override; end; [...] procedure TMyThead.MethodForSync; begin //Dem TImage aus dem Hauptform das ganze zuweisen DeinHauptForm.Image1.Picture.Bitmap.Assign(ThumbPicAusThread) end; procedure TMyThead.Execute; begin //Thumb zerugen Synchronize(MethodForSync); end; |
Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher
Zitat:
Delphi-Quellcode:
Mein Thread:
Type TFoto = record // Was alles drin sein kann
FileScr: String; Vorschau: TBitmap; end; Type pTFoto = ^TFoto; // Pointer für den Record
Delphi-Quellcode:
Ich schreibe nochmals, dass jede andere Prozedur, sei es Canvas.Draw(..), Canvas.Rectangle oder ähnliches anstelle des StretchDraw wunderbar funktioniert und jedes Mal gezeichnet wird!
type
Vorschaubildererstellen = class(TThread) public constructor INIT(Daten: TFotoShow; Gaug: TGauge; Gri: TStringgrid; Pane: TPanel); private { Private-Deklarationen } mFotos: TFotoShow; // Für den Daten Zugriff aufs Form Übergabe der Pointer Gauge: TGauge; Grid: TStringgrid; Panel: TPanel; protected procedure Vorschauerstelleneinzeln(Nr,Gr: integer; Fot: pTFoto); procedure Execute; override; end; implementation uses main; constructor Vorschaubildererstellen.INIT(Daten: TFotoShow; Gaug: TGauge; Gri: TStringgrid; Pane: TPanel); begin mFotos := Daten; Gauge := Gaug; Grid := Gri; Panel := Pane; inherited create(false); end; procedure Vorschaubildererstellen.Execute; // Thread var i: integer; tmp : pTFoto; begin for i := 0 to mFotos.AnzahlFotos-1 do begin tmp := mFotos.Elemente.Items[i]; if tmp^.Vorschau = nil then begin Vorschauerstelleneinzeln(i,mFotos.VorschauGr,tmp); end; end; end; procedure Vorschaubildererstellen.Vorschauerstelleneinzeln(Nr,Gr: integer; Fot: pTFoto); var LadImage: Timage; Verh: Double; hoehe, weite,x: integer; Extention: String; LadBitmap: TBitmap; jpg: TJPEGImage; MegaP: Real; Verk: TBildverkleiner; begin try Extention := Ansilowercase(Extractfileext(Fot^.FileScr)); if Fot^.Vorschau = nil then Fot^.Vorschau := TBitmap.Create; if (Extention = '.jpg') OR (Extention = '.jpeg') then begin /// JPGS schnell!!!! --------------------------------- LadBitmap := TBitmap.Create; jpg := TJPEGImage.create; jpg.LoadFromFile(Fot^.FileScr); MegaP := (JPG.Width*JPG.Height)/1000000; if MegaP > 1 then JPG.Scale := jsEighth ELSE // schnell!! if MegaP > 0.3 then JPG.Scale := jshalf ELSE JPG.Scale := jsFullSize; LadBitmap.Assign(jpg); if (LadBitmap.Width > 0) AND (LadBitmap.Height > 0)then begin Verh := LadBitmap.Width/LadBitmap.Height; Fot^.Vorschau.Width := Gr; Fot^.Vorschau.Height := Gr; if Verh >= 1 then begin hoehe := Round(Gr/Verh); x := round((Gr-hoehe)/2); Fot^.Vorschau.Canvas.StretchDraw(Rect(0,x,Gr,hoehe+x),LadBitmap); // HIER wird gemalt end ELSE begin weite := Round(Gr*Verh); x := round((Gr-weite)/2); Fot^.Vorschau.Canvas.StretchDraw(Rect(x,0,weite+x,gr),LadBitmap); // HIER wird gemalt end; end; jpg.Free; LadBitmap.Free; end ELSE begin /// BMPS oder anderes end ELSE begin Fot^.Vorschau := nil; end; LadImage.Free; end; except Fot^.Vorschau := nil; end; end; |
Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher
die stellen mit "//HIER wird gemalt" müsstest du in eine extra procedure packen, und diese dann mit
Code:
aufrufen.
Syncronize(Proc);
informier dich ansonsten nochmal in der Hlife über die funktionsweise von TThread.Syncronize(). |
Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher
Zitat:
|
Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher
Delphi-Quellcode:
canvas.lock
canvas.unlock |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:35 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-2025 by Thomas Breitkreuz