AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Bitmap in Thread laden
Thema durchsuchen
Ansicht
Themen-Optionen

Bitmap in Thread laden

Ein Thema von Gruber_Hans_12345 · begonnen am 16. Mär 2009 · letzter Beitrag vom 19. Jun 2012
Antwort Antwort
Seite 1 von 2  1 2      
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.426 Beiträge
 
Delphi 2007 Professional
 
#1

Bitmap in Thread laden

  Alt 16. Mär 2009, 15:21
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
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#2

Re: Bitmap in Thread laden

  Alt 16. Mär 2009, 15:34
Zitat von Gruber_Hans_12345:
Threadsafe ist alles
Nope, TCanvas, TBitmap, TBrush, TPen, etc sind es nicht...
  Mit Zitat antworten Zitat
busybyte

Registriert seit: 15. Sep 2006
165 Beiträge
 
#3

Re: Bitmap in Thread laden

  Alt 16. Mär 2009, 15:40
Code?
I love DiscCat
  Mit Zitat antworten Zitat
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.426 Beiträge
 
Delphi 2007 Professional
 
#4

Re: Bitmap in Thread laden

  Alt 16. Mär 2009, 22:05
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
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.426 Beiträge
 
Delphi 2007 Professional
 
#5

Re: Bitmap in Thread laden

  Alt 16. Mär 2009, 22:13
wobei, reicht nicht ein einfaches canvas.lock?

bzw. die zwei threads greifen eh nicht auf den selben canvas zu ...?
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
Benutzerbild von alleinherrscher
alleinherrscher

Registriert seit: 8. Jul 2004
Ort: Aachen
797 Beiträge
 
Delphi XE2 Professional
 
#6

Re: Bitmap in Thread laden

  Alt 17. Mär 2009, 00:55
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:

Multithreading with Delphi: Basic synchronisation
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.429 Beiträge
 
Delphi 10.4 Sydney
 
#7

Re: Bitmap in Thread laden

  Alt 17. Mär 2009, 08:17
Zitat von alleinherrscher:
Du kannst Threads synchronisieren indem du TThread.Synchronize aufrufst und als Argument eine parameterlose Prozedur übergibst, die dann dein Bitmap läd.
Dann wäre aber der eigene Thread zum Laden der Grafik sinnlos, da die Arbeit doch wieder im Mainthread erfolgt.
  Mit Zitat antworten Zitat
Benutzerbild von alleinherrscher
alleinherrscher

Registriert seit: 8. Jul 2004
Ort: Aachen
797 Beiträge
 
Delphi XE2 Professional
 
#8

Re: Bitmap in Thread laden

  Alt 17. Mär 2009, 08:54
Zitat von Blup:
Zitat von alleinherrscher:
Du kannst Threads synchronisieren indem du TThread.Synchronize aufrufst und als Argument eine parameterlose Prozedur übergibst, die dann dein Bitmap läd.
Dann wäre aber der eigene Thread zum Laden der Grafik sinnlos, da die Arbeit doch wieder im Mainthread erfolgt.
Dann muss er halt das Bitmap im Thread laden und anschließend per CopyFrom oder per Bitblt synchronisiert auf die Oberfläche bringen... müsste doch gehen oder? Ich überleg grad nur, ob sich dann die Katze wieder in den Schwanz beißt...
„Software wird schneller langsamer als Hardware schneller wird. “ (Niklaus Wirth, 1995)

Mein Netzwerktool: Lan.FS
  Mit Zitat antworten Zitat
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.426 Beiträge
 
Delphi 2007 Professional
 
#9

Re: Bitmap in Thread laden

  Alt 17. Mär 2009, 08:55
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:
{$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;
Code im main, der auf den Thread zugreift (der restliche code arbeitet mit dem Picshow Element)

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;
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.426 Beiträge
 
Delphi 2007 Professional
 
#10

Re: Bitmap in Thread laden

  Alt 17. Mär 2009, 09:00
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:
        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;
und es funktioniert auch nicht?
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:47 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz