![]() |
Bitmap in Thread laden
Gibt es irgendwas zu beachten, wenn ich ein TBitmap in einem Thread lade?
Habe eine funktionierende procedure, die wenn ich sie in einen Thread auslagere, nur mehr ein schwarzes TBitmap liefert ... Threadsafe ist alles |
Re: Bitmap in Thread laden
Zitat:
|
Re: Bitmap in Thread laden
Code?
|
Re: Bitmap in Thread laden
hmmmm, dann baue ich mal um, das ich im thread nur mehr per Windows API arbeite, dann sollte es mit dem Thread ja keine probs mehr geben.
den da einzige was der thread macht ist ein jpeg laden, dieses in ein bitmap wandeln und dann stretchen -> das wars |
Re: Bitmap in Thread laden
wobei, reicht nicht ein einfaches canvas.lock?
bzw. die zwei threads greifen eh nicht auf den selben canvas zu ...? |
Re: Bitmap in Thread laden
Dein Programm hat aber einen Main VCL Thread für Eingaben und Ausgaben auf deinem Formular. Daher müssen deine Threads in erster Linie mal mit diesem Thread synchronisiert werden.
Du kannst Threads synchronisieren indem du TThread.Synchronize aufrufst und als Argument eine parameterlose Prozedur übergibst, die dann dein Bitmap läd. edit: Grade mal gegoogelt und einen sehr informativen Text auf englisch gefunden: ![]() |
Re: Bitmap in Thread laden
Zitat:
|
Re: Bitmap in Thread laden
Zitat:
|
Re: Bitmap in Thread laden
Hmmm, ich weiss was synchronisation ist, und "meine" teile isnd ja durchaus synchron ... nur weiss ich nicht wie ichs mit der VCL machen soll.
Ich kann ja nicht absolut alles synchronisieren, dann bringt mir der thread ja nix?!?!?!? Thread Code
Delphi-Quellcode:
Code im main, der auf den Thread zugreift (der restliche code arbeitet mit dem Picshow Element)
{$DEFINE USE_THREADLOADING}
procedure TLoadImage.DoLoadImage(FileName : string); var picRect : TRect; pWidth : integer; pHeight : integer; jp : TJPEGImage; pic : TPicture; begin EnterCriticalSection(fCS); try if FileName = '' then exit; OutputDebugString(PChar('Loading image ' +FileName)); fInLoad := TRUE; fLoadedImage := ''; jp := TJPEGImage.Create; jp.LoadFromFile(FileName); pWidth := jp.Width; pHeight := jp.Height; if assigned(fBitmap) then fBitmap.Free; fBitmap := TBitmap.Create; fBitmap.Width := 1280; fBitmap.Height := 1024; fBitmap.PixelFormat := pf32bit; fBitmap.Canvas.Brush.Color := clBlack; Windows.FillRect(fBitmap.Canvas.Handle, Rect(0,0,fBitmap.Width, fBitmap.Height), fBitmap.Canvas.Brush.Handle); if (pWidth / pHeight) > (1280 / 1024) then begin picRect := Rect(0, (1024 - round((1280 / pWidth) * pHeight)) div 2, 1280, 0); picRect.Bottom := fBitmap.Height - picRect.Top; end else begin picRect := Rect(1280 - (round((1024 / pHeight) * pWidth)) div 2, 0, 0, 1024); picRect.Right := fBitmap.Width - picRect.Left; end; fBitmap.Canvas.StretchDraw(picRect, jp); fLoadedImage := FileName; fInLoad := FALSE; fFileName := ''; OutputDebugString(PChar('Finish Loading image ' +fLoadedImage)); finally jp.Free; LeaveCriticalSection(fCS); end; end;
Delphi-Quellcode:
procedure TMainForm.LoadNextImage;
begin {$IFDEF USE_THREADLOADING} if not TryEnterCriticalSection(imgLoader.fCS) then begin OutputDebugString('Bild noch nicht vollständig geladen Recheck in 100ms'); trCheckLoadImage.Interval := 100; trCheckLoadImage.Enabled := TRUE; exit; end; try if imgLoader.LoadedImage = '' then begin OutputDebugString('No image loaded Recheck in 1000ms'); trCheckLoadImage.Interval := 1000; trCheckLoadImage.Enabled := TRUE; imgLoader.LoadImage(PicturesPath + '\' + GetNextImageName(LoadedImage)); exit; end; LoadedImage := ExtractFileName(imgLoader.LoadedImage); OutputDebugString(PChar('Image loaded : Using image : '+LoadedImage)); {$ELSE} imgLoader.DoLoadImage(PicturesPath + '\' + GetNextImageName(LoadedImage)); {$ENDIF} Picshow.Picture.Bitmap.Width := imgLoader.Bitmap.Width; Picshow.Picture.Bitmap.Height := imgLoader.Bitmap.Height; Picshow.Picture.Bitmap.PixelFormat := imgLoader.Bitmap.PixelFormat; BitBlt(PicShow.Picture.Bitmap.Canvas.Handle, 0, 0, Picshow.Picture.Bitmap.Width, Picshow.Picture.Bitmap.Height , imgLoader.Bitmap.Canvas.Handle, 0, 0, SRCCOPY); {$IFDEF USE_THREADLOADING} imgLoader.LoadImage(PicturesPath + '\' + GetNextImageName(LoadedImage)); finally LeaveCriticalSection(imgLoader.fCS); trCheckLoadImage.Interval := 2000; trCheckLoadImage.Enabled := TRUE; end; {$ENDIF} end; |
Re: Bitmap in Thread laden
Also ich habe das Gefühl, es hat mit irgendwas anderes zu tun hier ...
habe im hautpthread jetzt ein lock eingebaut, das gewartet wird, bis das bild da ist ...
Delphi-Quellcode:
und es funktioniert auch nicht?
finally
LeaveCriticalSection(imgLoader.fCS); // Hauptthread blockieren, bis image geladen ist sleep(100); EnterCriticalSection(imgLoader.fCS); LeaveCriticalSection(imgLoader.fCS); trCheckLoadImage.Interval := 2000; trCheckLoadImage.Enabled := TRUE; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:05 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