AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TImage.Refresh in Lazarus

Ein Thema von Captain Albern · begonnen am 16. Feb 2019 · letzter Beitrag vom 20. Feb 2019
Antwort Antwort
Captain Albern

Registriert seit: 15. Feb 2019
11 Beiträge
 
#1

AW: TImage.Refresh in Lazarus

  Alt 17. Feb 2019, 11:36
PS: Folgender Code funktioniert (eine neue Zeile). Sieht dämlich aus, ist aber so.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var y,x : Integer;
          Line : Array [0..959] of Byte;
begin
  Image1.Width:=320;
  Image1.Height:=240;
  Image1.Picture.Bitmap.Width:=319;//Neu eingefügt, eigentlich nutzlos
  Image1.Picture.Bitmap.Width:=320;
  Image1.Picture.Bitmap.Height:=240;
  image1.Picture.Bitmap.PixelFormat:=pf24Bit;
  for y := 0 to 239 do begin
    for x := 0 to 959 do
      Line[x]:=Random($FF);
    Move(Line[0],Image1.Picture.Bitmap.ScanLine[y]^,960);
  end;
  Image1.Refresh;
end;
  Mit Zitat antworten Zitat
Captain Albern

Registriert seit: 15. Feb 2019
11 Beiträge
 
#2

AW: TImage.Refresh in Lazarus

  Alt 18. Feb 2019, 12:21
Ich bin's nochmal.

der letzte Code, den ich gepostet habe funktioniert zwar, ist aber nicht nur eine grauenhafte Umgehungslösung, sondern auch noch sehr langsam. Beim Ändern der Größe wird Speicher neu allokiert und das dauert.

Ich habe gemessen: Für ein Bild mit knapp 2MPixeln dauert das Kopieren der Daten 0,8ms, das Refreshen inkl. Größenänderung dauert >280ms. Das kann keine Lösung sein. Ich würde mich mit 10ms zufrieden geben, wobei ich glaube, dass auch das nicht Stand der Technik ist.

Ich glaube langsam, dass eine Komponente einen Bug hat. Dass es irgendwo ein changed-Flag gibt, das anzeigt, ob das Bild wirklich geändert ist und neu gezeichnet werden soll. Und da stimmt irgendwas nicht. Ich bin mal mit dem Debugger Schritt für Schritt durch Refresh gesteppt, aber da werden soviele administrative Dinge erledigt, da sehe ich nicht durch.
  Mit Zitat antworten Zitat
matashen

Registriert seit: 29. Jan 2007
Ort: daheim
483 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#3

AW: TImage.Refresh in Lazarus

  Alt 18. Feb 2019, 12:45
Hi,

schonmal im lcl\include graphic.inc geguckt ob die changed(self) alle sauber drin sind wo es bei dir hakt.
Bin mir nicht sicher ob in dem Code das repaint / refresh sitzt, aber einfach mal durch die includes durchhangeln
Matthias
Das Leben ist eines der härtesten.
  Mit Zitat antworten Zitat
Captain Albern

Registriert seit: 15. Feb 2019
11 Beiträge
 
#4

AW: TImage.Refresh in Lazarus

  Alt 18. Feb 2019, 13:40
Zwischendurch habe ich gedacht, es würde funktionieren, wenn ich ein TBitmap ohne TImage erzeuge, und dieses mit Form.Canvas.Draw direkt auf das Form zeichne. Aber auch das funktioniert nur einmal und aktualisiert dann nicht mehr.

Also habe ich weiter verfolgt, was beim Draw Passiert. Jede Menge administratives Zeug und letztendlich der Aufruf von Windows.BitBlt. Also habe ich das versucht und es gibt immer noch das gleiche Ergebnis: Einmaliges Update.

Mit dem BitBlt habe ich gelernt, dass TBitmap selbst ein TCanvas besitzt und dieses Canvas auf die Ziel-Canvas kopiert wird. Also habe ich mal versucht, nicht nur die Scanlines mit Daten zu füllen, sondern auf dem TBitmap.Canvas etwas zu zeichnen. Und siehe da: DIESE Änderungen werden tatsächlich aktualisiert dargestellt. Es muss also daran liegen, dass das TBitmap die Informationen aus den Scanlines nicht auf das eigene Canvas überträgt. Folgender Beispielcode ändert sowohl die Scanlines und malt ein sich änderndes Rechteck. Selbst wenn die Random jedes Mal die gleichen Daten liefern würden, müssten sie hinter dem Rechteck wieder zum Vorschein kommen, da sie jedes Mal wieder neu in die Scanlines kopiert werden. Das Rechteck wächst aber...

Delphi-Quellcode:
procedure TForm1.FormShow(Sender: TObject);
begin
  B:=TBitmap.Create;
  B.Width:=320;
  B.Height:=240;
  B.PixelFormat:=pf24Bit;
  Counter:=1;
end;

procedure TForm1.Button1Click(Sender: TObject);
var x,y,w,h : Integer;
          Line : Array of Record b,g,r : Byte;end;
begin
  Counter:=Counter+1;
  w:=B.Width;
  h:=B.Height;
  SetLength(Line,W);
  for y := 0 to H-1 do begin
    for x := 0 to W-1 do begin
      Line[x].r:=Random($FF);
      Line[x].g:=Random($FF);
      Line[x].b:=Random($FF);
    end;
    Move(Line[0],B.ScanLine[y]^,3*W);
  end;
  SetLength(Line,0);
  B.Canvas.FillRect(10,10,20+Counter,20);
  Canvas.Draw(0,0,B); //die gleiche Wirkung hat...
// BitBlt(Canvas.Handle, 0, 0, W, H, B.Canvas.Handle, 0, 0, SRCCOPY);
end;

Geändert von Captain Albern (18. Feb 2019 um 19:26 Uhr)
  Mit Zitat antworten Zitat
Captain Albern

Registriert seit: 15. Feb 2019
11 Beiträge
 
#5

AW: TImage.Refresh in Lazarus

  Alt 18. Feb 2019, 19:52
Entschuldigung, ich hoffe es nervt nicht zu sehr, aber die ganzen bisherigen Bemühungen haben nichts gebracht.

Kann bitte jemand einmal ein Code-Beispiel posten, wie mit Lazarus Rasterdaten in irgendeiner Form auf den Bildschirm gezeichnet werden. Und vor allem, wenn sie sich ändern auch aktualisiert dargestellt werden. Nach Möglichkeit ohne irgendwelche zusätzlichen Packages zu installieren.
Vielen Dank im Voraus !

Es sollte aber mit Lazarus funktionieren. Ich habe gerade kein Delphi installiert, aber ich bin mir fast sicher, dass es früher mit Delphi einfach mit einem Refresh ohne große Umstände funktioniert hat.

Gruß
C.A.
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.277 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: TImage.Refresh in Lazarus

  Alt 18. Feb 2019, 20:11
Hallo,
vielleicht hilft dir das?
http://forum.lazarus.freepascal.org/...?topic=40433.0
Heiko
  Mit Zitat antworten Zitat
matashen

Registriert seit: 29. Jan 2007
Ort: daheim
483 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#7

AW: TImage.Refresh in Lazarus

  Alt 19. Feb 2019, 15:13
und evtl mal in die canvas.inc gucken, evtl hilft im Draw ein Changing und Changed wie im DrawFocusrect
Delphi-Quellcode:
Procedure TCanvas.Draw(X, Y: Integer; SrcGraphic: TGraphic);
var
  ARect: TRect;
begin
  if not Assigned(SrcGraphic) then exit;
  ARect:=Bounds(X,Y,SrcGraphic.Width,SrcGraphic.Height);
  StretchDraw(ARect,SrcGraphic);
end;

{-----------------------------------------------}
{--  TCanvas.DrawFocusRect --}
{-----------------------------------------------}
procedure TCanvas.DrawFocusRect(const ARect: TRect);
begin
  Changing;
  RequiredState([csHandleValid]);
  LCLIntf.DrawFocusRect(FHandle, ARect);
  Changed;
end;
Matthias
Das Leben ist eines der härtesten.

Geändert von matashen (19. Feb 2019 um 15:15 Uhr) Grund: formatierung
  Mit Zitat antworten Zitat
Antwort Antwort

 

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 22:24 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