Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Temporäres Einfrieren beim Zeichnen einer BitMap (https://www.delphipraxis.net/168865-temporaeres-einfrieren-beim-zeichnen-einer-bitmap.html)

compix 14. Jun 2012 23:18

Delphi-Version: 7

Temporäres Einfrieren beim Zeichnen einer BitMap
 
Hallo :),
ich habe ein kleines Test-Programm geschrieben, um mit Bitmaps zu experimentieren:
Delphi-Quellcode:
var
  Form1: TForm1;
  BG: TBitMap;

  SCREEN: TBitMap;
  ABBRECHEN: boolean;
implementation

{$R *.dfm}

procedure TForm1.FormDestroy(Sender: TObject);
begin
  BG.Free;
  SCREEN.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  SCREEN := TBitMap.Create;
  SCREEN.Width := 1600;
  SCREEN.Height := 1200;

  BG := TBitMap.Create;
  BG.LoadFromFile('background.bmp'); //5,5 MB großes Bild(1600x1200) wird geladen

  SCREEN.Canvas.Draw(0,0,BG);
  ABBRECHEN := false;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  while (not ABBRECHEN) do
  begin
    Canvas.Draw(0,0,SCREEN);

    application.ProcessMessages;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ABBRECHEN := true;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  ABBRECHEN := true;
end;
Wie man unschwer erkennen kann wird lediglich ein Hintergrundbild in einer While-Schleife wiederholt auf die Canvas der Form1 gezeichnet.
Wenn ich das Programm allerdings ausführe und mit einem Button-Klick die Schleife betrete, wechselt mein Computer ständig vom eingefrorenen Zustand zum "Normal"-Zustand. Der Mauszeiger bleibt also kurz unbeweglich, wird wieder beweglich -> unbeweglich ad infinitum.
Ersetze ich nun Canvas.Draw(0,0,SCREEN) mit Canvas.Draw(0,0,BG) ist alles in Ordnung, auch das Hinzufügen eines "sleep(1)" behebt dieses Problem.
Scheinbar liegt es an:
Delphi-Quellcode:
  SCREEN.Width := 1600;
  SCREEN.Height := 1200;
Aber wieso ?
Ich Hoffe ihr könnt mir diese Frage beantworten,
MfG, compix

Dalai 15. Jun 2012 02:11

AW: Temporäres Einfrieren beim Zeichnen einer BitMap
 
Öhm,
Delphi-Quellcode:
Screen
ist eine vordefinierte Variable aus einer VCL-Unit (weiß nicht welche). Vielleicht kommt es sich damit in die Haare.

MfG Dalai

jaenicke 15. Jun 2012 06:06

AW: Temporäres Einfrieren beim Zeichnen einer BitMap
 
Versuche es doch mal "richtig":
Benutze eine TPaintBox und zeichne dein fertiges Bild in dessen OnPaint auf deren Canvas.

Zum Auslösen des Neuzeichnens musst du dann nur noch Invalidate der PaintBox aufrufen.

Die Variable Screen kann kaum verwechselt werden, da Draw eine TGraphic oder so erwartet und die eigene Variable näher dran deklariert ist, aber nichtsdestotrotz wären bessere Bezeichner natürlich trotzdem sinnvoll. (Nicht alles groß schreiben, ruhig nicht nur ein Wort, am besten als Feld unter private mit F am Anfang, ...)

Bummi 15. Jun 2012 06:14

AW: Temporäres Einfrieren beim Zeichnen einer BitMap
 
Da ich das von Dir beschriebene Phänomen gedanklich nicht nachvollziehen kann, habe ich es kurz nachgestellt (WIN7 / D2010), auch hier macht es keinen Unterschied ob ich BG oder SCREEN verwende, wie erwartet ca. 100% Last auf einem Kern, Programm bleibt durch Application.Prozessmessages bedienbar. (D7 habe ich leider gerade nicht zur Hand)

Ich hoffe aber dass es sich hier nur um Experimente handelt und Du ähnliches im OnPaint des Formulares abfackeln würdest.

Blup 15. Jun 2012 07:06

AW: Temporäres Einfrieren beim Zeichnen einer BitMap
 
Vergleiche Pixelformat von SCREEN und BG.

himitsu 15. Jun 2012 09:03

AW: Temporäres Einfrieren beim Zeichnen einer BitMap
 
SCREEN wird 24 Bit haben (es sei denn die grafikkrte wurde auf weniger eingestellt, aber das macht ja keiner mehr)



Lass' doch einfach die Schleife weg und nutze einen Timer.
Mit einem Intervall von 20 Millisekunden bekommt man auch locker mal 50 FPS hin.

Aber wenn sich sowieso nichts im Bild ändert, dann ist natürlich die PaintBox vorzuziehen.
Abgesehn davon, wenn über die ganze Form gezeichnet wird, dann kann man auch direkt drauf malen und das OnPaint der Form nutzen.



Und wieso sind BG, SCREEN und ABBRECHEN global, obwohl sie nur innerhalb dieser Klasse verwendet werden?

compix 16. Jun 2012 12:37

AW: Temporäres Einfrieren beim Zeichnen einer BitMap
 
Vielen Dank für eure Antworten und tut mir leid, dass ich nicht früher antworten konnte.

Tatsächlich ist Screen schon vordefiniert, das habe ich nicht gewusst, sofort geändert :)
und die globalen Deklarationen könnt ihr mir hoffentlich verzeihen ^^.

Inwiefern eine Paintbox sinnvoller ist verstehe ich nicht, wie gesagt sollte es ja nur ein Test sein. Wenn ich z.B. ein Spiel programmiere,
indem ich in einer Schleife das Zeichnen zeitlich steuern muss dann macht es doch keinen Sinn, wenn ich das in ein OnPaint-Event packe.

Auch mit Delphi 2010 habe ich dieses Problem unter Windows XP Prof. und die Lösung scheint tatsächlich in meinem Fall das Pixelformat zu sein:
(SCREEN wurde umbenannt in BACKBUFFER)
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  BACKBUFFER := TBitMap.Create;
  BACKBUFFER.Width := 1600;
  BACKBUFFER.Height := 1200;
  BACKBUFFER.PixelFormat := pf24bit;

  BG := TBitMap.Create;
  BG.LoadFromFile('background.bmp'); //5,5 MB großes Bild(1600x1200) wird geladen

  BACKBUFFER.Canvas.Draw(0,0,BG);
  ABBRECHEN := false;
end;
Damit ist das Problem behoben :), vielen Dank.
MfG, compix


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:25 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