wie man ständig wechselnde Grafiken zeichnet

Habe das noch nicht gemacht außer in Java, Schau wieSteve McLeod repariert es), also offensichtlich sauge ich dran. Hier werden 64 Pixel um die aktuelle Mausposition auf einem Formular etwas größer gezeichnet. Das Problem ist, dass es "irgendwie" zu langsam ist und ich keine Ahnung habe, wo ich anfangen soll, es zu reparieren.

Abgesehen davon habe ich einen Timer-Thread erstellt, der ständig Aktualisierungsgrafiken aufruft, wenn er fertig ist, und ein wenig fps wie Text, um zu zeigen, wie schnell Dinge gezeichnet werden.

eispiel @Image: (Bild stammt aus dem Buchstaben 'a' in "IntelliTrace" in Microsoft VS2010)

Quellenbeispiel:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace Zoom
{
    public partial class Form1 : Form
    {
        static class dllRef
        {
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            static extern bool GetCursorPos(out Point lpPoint);

            [DllImport("user32.dll")]
            static extern IntPtr GetDC(IntPtr hwnd);

            [DllImport("user32.dll")]
            static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);

            [DllImport("gdi32.dll")]
            static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);

            // from http://www.pinvoke.net/default.aspx/gdi32/GetPixel.html
            static public System.Drawing.Color getPixelColor(int x, int y) {
                IntPtr hdc = GetDC(IntPtr.Zero);
                uint pixel = GetPixel(hdc, x, y);
                ReleaseDC(IntPtr.Zero, hdc);
                Color color = Color.FromArgb((int)(pixel & 0x000000FF),
                             (int)(pixel & 0x0000FF00) >> 8,
                             (int)(pixel & 0x00FF0000) >> 16);
                return color;
            }
            static public System.Drawing.Point getMousePosition() {
                Point p = new Point();
                GetCursorPos(out p); 
                return p;
            }
        }

        public Form1() {
            InitializeComponent();
            this.Size = new Size(400,400);
            this.Text="Image zoom";
            this.Location = new Point(640, 0);
            this.image = new Bitmap(320, 320);
            this.timeRef = DateTime.Now;
            this.BackColor = Color.White;
            Timer t = new Timer();
            t.Interval = 25;
            t.Tick += new EventHandler(Timer_Tick);
            t.Start();
        }

        public void Timer_Tick(object sender, EventArgs eArgs) {
            this.Form1_Paint(this, new PaintEventArgs(this.CreateGraphics(), new Rectangle(0, 0, this.Width, this.Height)));
        }

        private bool isdone = true;
        private int iter = 0;
        private Bitmap image;
        private DateTime timeRef;
        private void Form1_Paint(object sender, PaintEventArgs e) {
            if (isdone) {
                isdone = false;
                int step = 40;
                Point p = dllRef.getMousePosition();
                Pen myPen = new Pen(Color.Gray, 1);
                SolidBrush myBrush = null;
                Bitmap image2 = new Bitmap(320, 340);

                Graphics gc = Graphics.FromImage(image2);

                for (int x = 0; x < 8; x++) {
                    for (int y = 0; y < 8; y++) {
                        myBrush = new SolidBrush(dllRef.getPixelColor(p.X - 4 + x, p.Y - 4 + y));
                        gc.FillEllipse(myBrush, x * step, y * step, step - 3, step - 3);
                        gc.DrawEllipse(myPen, x * step, y * step, step - 3, step - 3);
                    }
                }
                StringBuilder sb = new StringBuilder();
                sb.Append(iter)
                        .Append(" frames in ")
                        .Append(String.Format("{0:0.###}", ((DateTime.Now-this.timeRef).TotalMilliseconds)/1000))
                        .Append("s.");
                gc.FillRectangle(new SolidBrush(this.BackColor), new Rectangle( 0, 320, 320, 40));
                gc.DrawString(sb.ToString(),new Font("Arial", 12),new SolidBrush(Color.Black), 10, 320);
                gc.Dispose();
                isdone = true;
                iter++;
                image = image2;
            }
            e.Graphics.DrawImage(image, 35f, 15f);
        }
    }
}

Nach den vorgenommenen Änderungen ist diese ~ 98% schneller:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;


namespace Zoom
{
    public partial class Form1 : Form
    {
        static class dllRef
        {
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            static extern bool GetCursorPos(out Point lpPoint);

            [DllImport("user32.dll")]
            static extern IntPtr GetDC(IntPtr hwnd);

            [DllImport("user32.dll")]
            static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);

            [DllImport("gdi32.dll")]
            static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);

            // from http://www.pinvoke.net/default.aspx/gdi32/GetPixel.html
            static public System.Drawing.Color getPixelColor(int x, int y) {
                IntPtr hdc = GetDC(IntPtr.Zero);
                uint pixel = GetPixel(hdc, x, y);
                ReleaseDC(IntPtr.Zero, hdc);
                Color color = Color.FromArgb((int)(pixel & 0x000000FF),
                             (int)(pixel & 0x0000FF00) >> 8,
                             (int)(pixel & 0x00FF0000) >> 16);
                return color;
            }
            static public System.Drawing.Point getMousePosition() {
                Point p = new Point();
                GetCursorPos(out p); 
                return p;
            }
        }

        public Form1() {
            InitializeComponent();
            this.Size = new Size(400,400);
            this.Text="Image zoom";
            this.Location = new Point(640, 0);
            this.image = new Bitmap(320, 340);
            this.timeRef = DateTime.Now;
            this.BackColor = Color.White;
            Timer t = new Timer();
            t.Interval = 25;
            t.Tick += new EventHandler(Timer_Tick);
            t.Start();
        }

        public void Timer_Tick(object sender, EventArgs eArgs) {
            this.Form1_Paint(this, new PaintEventArgs(this.CreateGraphics(), new Rectangle(0, 0, this.Width, this.Height)));
        }

        private bool isdone = true;
        private int iter = 0;
        private Bitmap image;
        private DateTime timeRef;
        private void Form1_Paint(object sender, PaintEventArgs e) {
            if (isdone) {
                isdone = false;
                int step = 40;
                Point p = dllRef.getMousePosition();
                SolidBrush myBrush = null;
                Bitmap hc = new Bitmap(8, 8);

                using (Pen myPen = new Pen(Color.Gray, 1))
                using (Graphics gc = Graphics.FromImage(image))
                using (Graphics gf = Graphics.FromImage(hc))
                {
                    gf.CopyFromScreen(p.X - 4, p.Y - 4, 0, 0, new Size(8, 8),
                            CopyPixelOperation.SourceCopy);

                    for (int x = 0; x < 8; x++)
                    {
                        for (int y = 0; y < 8; y++)
                        {
                            myBrush = new SolidBrush(hc.GetPixel(x, y));
                            gc.FillEllipse(myBrush, x * step, y * step, step - 3, step - 3);
                            gc.DrawEllipse(myPen, x * step, y * step, step - 3, step - 3);
                        }
                    }

                    double ts = ((DateTime.Now - this.timeRef).TotalMilliseconds) / 1000;
                    StringBuilder sb = new StringBuilder();
                    sb.Append(++iter).Append(" frames in ").Append(String.Format("{0:0.###}", ts)).Append("s.");

                    gc.FillRectangle(new SolidBrush(this.BackColor), new Rectangle(0, 320, 320, 40));
                    gc.DrawString(sb.ToString(), new Font("Arial", 12), new SolidBrush(Color.Black), 10, 320);

                }

                isdone = true;
            }
            e.Graphics.DrawImage(image, 35f, 15f);
        }
    }
}

Antworten auf die Frage(2)

Ihre Antwort auf die Frage