AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Cross-Platform-Entwicklung [Fmx, Vcl] Verhalten von TBitmap in Threads

[Fmx, Vcl] Verhalten von TBitmap in Threads

Ein Thema von Rollo62 · begonnen am 12. Apr 2016 · letzter Beitrag vom 4. Okt 2018
Antwort Antwort
Rollo62

Registriert seit: 15. Mär 2007
4.228 Beiträge
 
Delphi 12 Athens
 
#1

AW: [Fmx, Vcl] Verhalten von TBitmap in Threads

  Alt 13. Apr 2016, 14:52
Hier ist mal ein kleiner Test.

@Sir Rufo
Als Basis habe ich deinen TBitmapProducerThread gefunden und ich habe versucht das zusammen mit einer ImageList auszuprobieren.
Der TBitmapProducerThread war wohl nur für VCL gedacht, aber auch mit FMX könnte das ja Laufen ?!

Ich erzeuge im Thread neue Bitmaps, die ich dann in die ImageList speichere
- Thread Erzeugen eines leeren Bitmaps
- UI-Thread per Syncronize Ändern der Größe (das wird mit dem Canvas in Berührung kommen)
- UI-Thread Übergabe des neuen Bitmaps

Im DoProduce rufe ich das ändernde SetSize mit Synchronize auf, und ändere dann mit Map/Unmap.
Anders komme ich doch an die Pixel nicht heran, ich könnte es noch mit Scanline probieren aber
Map/Unmap brauche ich womöglich trotzdem.

Delphi-Quellcode:
procedure TBitmapProducerThread.DoProduce(const LBitmap : TBitmap; LParams : TBitmapParameters);
var
  Data: TBitmapData;
  I: Integer;
  col: TAlphaColor;
begin

  TThread.Synchronize(nil,
                      procedure
                      begin
                        // This must be in Main Thread, to be treadsafe
                        LBitmap.Width := LParams.Width;
                        LBitmap.Height := LParams.Height;
                      end
                     );

  // Bitmap erstellen
  if LBitmap.Map(TMapAccess.ReadWrite, Data) then
  begin

    col := TAlphaColorF.Create(128+Random(127), 128+Random(127), 128+Random(127)).ToAlphacolor;

    // // 5000 xxx Pixel auf ein Bitmap malen
    for I := 1 to 5000 do
    begin
      Data.SetPixel(Random( LBitmap.Width ), //Muss noch Scanline probieren, als Alternative
                    Random( LBitmap.Height ),
                    col //TAlphaColorRec.Red
                   );
    end;

    LBitmap.Unmap(Data);
  end;

end;
Unter Windows läuft alles gut bis jetzt,
unter OSX gab es schon Exception, geht aber auch meistens
und unter Android geht es gar nicht.
Unter iOS habe ichs noch garnicht versucht ...

Aber zumindest habe ich mal getestet wie man Bitmaps einer ImageList zuordnen kann, über den Namen:
Delphi-Quellcode:
//
// wird von TBitmapProducerThread aufgerufen, im UI-Thread
//
procedure TForm1.EvOnBmpProdOutputChanged(Sender: TObject);
var
  isi: TSourceItem;
  mbi: TBitmapItem;
  idi: TDestinationItem;
  di: TDestinationItem;
  lay: TLayer;
  sX: string;
  bmi: TBitmapItem;
  ms: TMemoryStream;
  bmp: TBitmap;

begin

  bmp := TBitmap.Create;

  try
    FBmpProd.Get( bmp ); // Hier wird die Bitmap aus dem Thread geholt

    // Und hier wird ein Neuer ImageList-Eintrag angelegt
    isi := ImageList1.Source. Add as TSourceItem;
    if isi.MultiResBitmap.Count = 0 then
    begin
      bmi := isi.MultiResBitmap.Add as TBitmapItem;

      ms := TMemoryStream.Create;

      try
        bmp.SaveToStream( ms );
        ms.Position := 0;

        bmi.Bitmap.CreateFromStream( ms );

      finally
        ms.Free;
      end;

    end;

    sX := isi.Name;
    idi := ImageList1.Destination.Add as TDestinationItem;
    lay := idi.Layers.Add;
    lay.Name := sX; // Setup the link the the Source Bitmap here
    sX := lay.Name;
    lay.SourceRect.Rect := RectF(0, 0, 256, 256); // Region within the soure-Rect

  finally
    bmp.Free;
  end;

  ScrollBar1.Max := ImageList1.Destination.Count-1;
end;

Benutzung:
Append/Insert/Delete/Clear - Legt Items im Listview an, und benutzt ImageList als Basis.
Das geht recht fix, so das man keinen Thread braucht (ich zumindest noch nicht)).

Produce erzeugt neue Bitmaps in dem ImageView, die ich dann s.o. zum Erzeugen benutzen kann.


Rollo
Angehängte Dateien
Dateityp: zip S002_ImageListMag.zip (629,6 KB, 6x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Christoph Schneider
Christoph Schneider

Registriert seit: 7. Okt 2008
Ort: CH-Baar
56 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: [Fmx, Vcl] Verhalten von TBitmap in Threads

  Alt 3. Okt 2018, 09:43
Bei FMX sollte TBitmap heute aber Threadsafe sein (Stand Delphi 10.2 Tokyo):

http://docwiki.embarcadero.com/RADSt...and_TContext3D

Dabei aber unbedingt peinlich darauf achten, dass das Bitmap-Objekt nicht gleichzeitig aus mehreren Threads verwendet wird!
Wenn diese Regel verletzt wird sind die Folgen schmerzhaft: Ich kämpfte gerade mit sporadisch leeren TImage denen ein Bitmap zu gewiesen wurden, welches in einem Thread erstellt wurde.
Christoph Schneider
  Mit Zitat antworten Zitat
Benutzerbild von Christoph Schneider
Christoph Schneider

Registriert seit: 7. Okt 2008
Ort: CH-Baar
56 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: [Fmx, Vcl] Verhalten von TBitmap in Threads

  Alt 4. Okt 2018, 08:37
Offenbar gibt's unter FMX auch unter Delphi 10.2.3 immer noch Probleme.

Siehe RSP-19673
Christoph Schneider
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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:58 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