Laden...

[gelöst] Zeichnen langsam - Warum?

Erstellt von nebler vor 15 Jahren Letzter Beitrag vor 15 Jahren 2.167 Views
N
nebler Themenstarter:in
10 Beiträge seit 2009
vor 15 Jahren
[gelöst] Zeichnen langsam - Warum?

Hallo Leute,

ich weis das es Themen gibt die sich mit GDI+ und der Dauer beschäftigen, allerdings bin ich auf etwas interessantes gestoßen und versteh es nicht.

Aber zuerst mal hier meine kleine Messung.
Folgender Algorithmus: (Eigentlich nur dazu da, das es etwas bunt wird ...)
Dieser Algo. wird per Knopfdruck ausgeführt.

for(int x = 0; x < WIDTH; x++) 
{
for(int y = 0; y < HEIGHT; y++ )
	{
		red++;
		if( red > 255 )
		{
			red = 0;
			green++;
			if( green > 255 )
			{
				green = 0;
				blue++;
				if( blue > 255)
				{
					blue = 0;
				}
			}
		} 
					
					
		myColor = Color.FromArgb( red, green, blue );
		
		// HERE code to paint the point (1px x 1px)!!!		
	}
}

Folgendes Ergebnis:
[**KlassenTyp **mit **Objekt **über (mit der Methode)]: [Zeit]
PicuteBox mit Bitmap -> Graphics (drawRectangle): 2.3 s
PictureBox mit Bitmap (setPixel): 0.6 s
Panel mit Graphics (drawRectangle): 29.5 s
(gemesene Zeit bis das komplette Bild da ist).

Zum einen versteh ich das mit dem Panel nicht, da ich gesehen habe das bei neueren Frameworks das Canvas von Panel abgeleitet wird. Und meines wissens Canvas eine mächtige Klasse ist. Ich habe versucht das Panel auszublenden, dann wieder einzublenden. Hat alles nichts bedeutsames gebracht. Bin immer bei ca. 30 Sekunden. (Man kann hier beim Bildaufbau zu schauen, habe keine Möglichkeit gefunden dies im Hintergrund geschehen zu lassen und dann es wieder einzublenden, außer mit der Eigenschaft Visible)

Wenn ich eine "pseudo" Schleife um setPixel baue, bin ich immer noch unter einer Sekunde. Warum bin ich damit schneller wie über Graphics (drawRectangle)? Da das Graphics ja im Framework ja läuft, und somit ja eigentlich optimaler laufen sollte als mein Code.

Mein Resume daraus ist, das ich meine eigene Zeichnen-Methode über setPixel bauen sollte, allerdings gibt ja alles was man so braucht schon in Graphics. Aber diese brauchen zu lange. Warum?

Framework: v1.1

Vielen Dank!

Mit freundlichen Grüßen

nebler

p.s: die Optimierungsthreads beschäftigen sich alle damit, was bei onPaint passiert, und nicht bei Knopfdruck.

F
10.010 Beiträge seit 2004
vor 15 Jahren

Und natürlich ist deine Heranghensweise langsam, denn nach jedem Pixel zwingst du
deine GUI ein Paint durchzuführen.
Es hat schon einen grund, warum man im OnPaint zeichnet, oder in eine Bitmap, und
die dann "am stück" anzeigt.

Framework: v1.1 ?
Warum verwendest Du dieses 5 Jahre alte und lange überholte FW?
Die Expressversionen ab 2005 sind kostenlos.

Gelöschter Account
vor 15 Jahren

habe keine Möglichkeit gefunden dies im Hintergrund geschehen zu lassen und dann es wieder einzublenden, außer mit der Eigenschaft Visible)

.SuspendLayout
.ResumeLayout

Mein Resume daraus ist, das ich meine eigene Zeichnen-Methode über setPixel bauen sollte, allerdings gibt ja alles was man so braucht schon in Graphics. Aber diese brauchen zu lange. Warum?

testumgebung? optimierter code oder debug?
genauer code (also wie sieht die implementierung aus)?

ich zweifle diese ergebnisse stark an. nciht nur intuitiv sondern auch empirisch. meiner ansicht nach passt was an deiner implementierung nciht.

N
nebler Themenstarter:in
10 Beiträge seit 2009
vor 15 Jahren

Das meine Implmentierung völliger Schwachsinn ist, kann sein.
Wenn es so ist, fände ich es super, wenn ihr das mir sagen könntet.

@FZelle:
Ich verwende v1.1, weil dies vorgegeben wurde als Entwicklungsplatform. Darauf habe ich keinen Einfluss.

@JAck30lena:
.SupendLayout und .ResumeLayout haben auch nicht zu einem weiteren Erfolg geführt.
In MS Visual Studio 2003 .NET, im Modus Debug, allerdings sollte das ja auch damit schneller gehen als 30 Sekunden ... oder?!

Hier mal meine Implmentierung:

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;

namespace UI
{

	public class MainForm : Form
	{
		private Panel		MyPanel		= null;
		private Button		MyButton	= null;

		public MainForm()
		{
			InitComponents();
			this.Show();
		}

		#region Methods for GUI

		private void InitComponents()
		{
			this.SuspendLayout();

			this.CenterToScreen();
			this.Text = "Blub";
			this.Size = new Size( 1200, 900 );


			MyPanel			= new Panel();
			MyPanel.Dock	= DockStyle.Fill;
			this.Controls.Add(MyPanel);

			MyButton		= new Button();
			MyButton.Text	= "DRUCK MICH!!!";
			MyButton.Dock	= DockStyle.Top;
			MyButton.Click += new EventHandler(test);
			this.Controls.Add(MyButton);


			this.ResumeLayout( false );
		}

		#endregion

		private void test(object sender, EventArgs e)
		{
			Console.WriteLine("BEGIN PAINTING");
			DateTime startT = DateTime.Now;
			// ---
			MyPanel.SuspendLayout();
			Graphics g = MyPanel.CreateGraphics();
			
				Pen p = new Pen( Color.Blue );
 
				for(int x = 0; x < MyPanel.Width; x++ ) 
				{
					for(int y = 0; y < MyPanel.Height; y++ )
					{
						g.DrawRectangle( p, x,y,1,1);
					}

		
			}
			MyPanel.ResumeLayout( false );
			// ---
			DateTime endT = DateTime.Now;
			Console.WriteLine("END PAINT in " + (TimeSpan)(endT-startT));
		}

	}
}

Danke.

Bis dann,

nebler

1.665 Beiträge seit 2006
vor 15 Jahren

Vergiss CreateGraphics() sofort wieder. Das brauchst du nur in speziellen Fällen, aber eigentlich nie zum Zeichnen
[Tutorial] Zeichnen in Windows-Programmen (Paint/OnPaint, PictureBox)

1.002 Beiträge seit 2007
vor 15 Jahren

Hallo nebler,

gewöhn dir die Verwendung von Control.CreateGraphics() am besten gleich wieder ab 😉.

Control.CreateGraphics braucht man auch an anderen Stellen kaum und sollte es am besten gleich wieder vergessen.

m0rius

Edit: Da war wohl jemand schneller 😉 ...

Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg

Gelöschter Account
vor 15 Jahren

also genau so sollte man nciht zeichnen.

  1. das create graphics sollte niemals auf controls ausgeführt werden.
  2. über eine million mal draw rectangle aufzurufen kann eine weile dauern. damit muss man rechnen.
  3. datetime eignet sich nur bedingt zum zeitmessen. nimm lieber stopwatch
  4. debugcode ist zum zeitmessen weniger als suboptimal, da hier keinerlei optimierung verwended wird.
  5. wenn du richtig schnell pixelgenaue änderungen machen willst, dann ist c# sowieso fehl am platz

ansonsten kannst du dir auch mal das hier ansehen:

	[GetPixel und SetPixel um Längen geschlagen. 800 mal schneller ](http://www.mycsharp.de/wbb2/thread.php?threadid=29667)  
	[Bitmap-Manipulation (MemBitmap)](http://www.mycsharp.de/wbb2/thread.php?threadid=59354)
N
nebler Themenstarter:in
10 Beiträge seit 2009
vor 15 Jahren

@JnkyXl, m0rius:
Danke für den Hinweis. Hab es aus irgendeinem Tutorial so raus. Nun gut.
Danke nochmal für die Antwort(en).

@JAck30lena:
zu ...
... 1 danke für die Information

... 2 ja klar, allerdings gings ja mit den anderen Varianten schneller und da Canvas von Panel (bei neueren Frameworks) abgeleitet wird, hat es mich halt stark verwundert

... 3 okay, cool danke (war nur dafür gedacht um eben mal zu sehen wielange das braucht, immer noch genauer, wie wenn man mit der stoppuhr davor sitzt 😃)

... 4 s. 3

... 5 ob es pixel genau sein muss, bezweifle ich aber. aber dies lässt sich alles abklären.

Vielen Dank!

Dann wär das auich geklärt 😃

nebler

479 Beiträge seit 2008
vor 15 Jahren

Hallo nebler

beachte noch bitte [Hinweis] Wie poste ich richtig?. Punkt 6.

mfg.
markus111

[Follow me on Twitter](http://twitter.com/blendingsky)
Gelöschter Account
vor 15 Jahren

zu 5. pixelgenau war ein wenig unpräzise ausgedrückt. ich meinte eher damit, das sehr sehr viele operationen perfomant auf einem großen bild ausgeführt werden müssen. für große bilder und viele operationen eignet sich c++ besser bzw gleiche eine mächtige grafik-lib in c++, die vorzugsweise auch das teilweise laden/bearbeiten von großen bildern unterstützt. gdi+ ist da eher nciht geeignet.

N
nebler Themenstarter:in
10 Beiträge seit 2009
vor 15 Jahren

Vielen Dank für die Antworten!

Schönen Tag euch allen.

nebler

-erledigt-