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.
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.
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.
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
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)
> Codejunky <
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
also genau so sollte man nciht zeichnen.
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)
@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
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.