Entwickler-Ecke

Multimedia / Grafik - Flimmern auf einem TImage.... Leidiges Thema.


Alibi - Sa 08.02.03 02:31
Titel: Flimmern auf einem TImage.... Leidiges Thema.
Hi,
ich weiß, ein leidiges Thema, und ja, Doublebuffered := true hab ich.
Also folgende Situation:
2 TImages übereinander.
Auf dem Untereren wird ein Gitter gemalt (Auch ein Oszilloskop, Facharbeitszeit ;)) und auf dem dadrüber wird der Graph gemalt.
Nunja, der Graph wird mit 1000x Canvas.LineTo in einer Schleife gemacht.
Um das "Wandern" der Linie auf dem Oszilloskop darzustellen hab ich in der Schleife (Optional) ein Delay(1) eingefügt.

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure Delay(t: Integer);
var
  i: integer;
begin
  for i := 1 to t do begin
    sleep(1);
    Application.ProcessMessages;
  end;
end;


Hier der eigentliche Zeichencode:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
  Image.Canvas.Brush.Color := clWhite;;
  Image.Canvas.FillRect(Image.Canvas.ClipRect);
  Image.Canvas.Pen.Color := Shape4.Brush.Color;
  Image.Canvas.MoveTo(trunc(xs[0]),trunc(ys[0]));
  for i := 1 to high(xs) do begin
    Image.Canvas.LineTo(trunc(xs[i]),trunc(ys[i]));
    Delay(SEDelay.Value);
  end;

Das hintere Image wird nicht mehr angefasst, nachdem das Gitter einmal gezeichnet wurde.
Und das ganze Konstrukt flimmert wie nichts gutes, irgendjemand eine Idee?

Ich hatte statt einem TImage auch schon für das obere eine TPaintBox versucht. Damit ging es besser, aber die wird gelöscht, wenn irgendwas drüber kommt....


Aya - Sa 08.02.03 04:11

Hast du die Images eventuell auf einem Panel o.ä.?


Alibi - Sa 08.02.03 13:01

Ja, haben die einfluss?
K, habs ausprobiert, geht wunderbar. :)
Thx.


Delphianer23 - Sa 08.02.03 15:12

Warum brauchst du denn überhaupt 2 images übereinander?

Zeiche doch alles in eins.


DaRkFiRe - Sa 08.02.03 16:04

Um das Flimmern zu vermeiden würde ich auch dazu raten, alles in ein Image zu zeichnen: ABER:

Ich habe die Erfahrung gemacht, dass es nicht flimmert (selbst bei öfterem Zeichnen pro Sekunde), wenn man nicht DIREKT auf das Canvas von TImage zeichnet, sondern auf eine temp. Bitmap (lokal erzeugt, exakt so groß wie die TImage-Komponente) und sie dann auf das TImage-Canvas malt (per CopyRect oder Draw). Das geht bei mir teuflisch schnell und OHNE FLIMMERN!


Aya - Sa 08.02.03 16:31

Alibi hat folgendes geschrieben:
Ja, haben die einfluss?

Ja, haben sie.. :)
Denn bei jedem Panel müßtest du dann auch Panel.DoubleBuffered:=True machen *g*

Au'revoir,
Aya


DaRkFiRe - Sa 08.02.03 17:57

Ach ja: Nachtrag!

SLEEP (x) ist einfach nur Frums! Meiner Erinnerung nach hält Sleep die ganze Anwendung an und das ist irgendwie sch***. Ich würde das so vorschlagen:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure waitdelay (ms_delay:LONGINT);
var lTick:LONGINT;
begin
  lTick:=GetTickCount;
  repeat
    Application.ProcessMessages; //andere Nachrichten werden noch (parallel!!!) verarbeitet
  until (GetTickCount - lTick > ms_delay);
end;


Dann einfach waitDelay aufrufen und als Parameter die Wartezeit in Millisekunden übergeben (wohl gemerkt der Prozedur übergeben, nich auf'n Teppich kotzen *g* - was'n Wortwitz!)...


Alibi - So 09.02.03 14:43

Hi,
danke für alles, flimmert nichts mehr und die Delay Procedure wurde ersetzt. :)
Ich habe mich nun auch von dem 2. Image für den Hintergrund getrennt und ein TPicture als Variable genommen, welche auf das Bild raufkopiert wird.