C# 如何绘制不断变化的图形

C# 如何绘制不断变化的图形,c#,graphics,gdi+,C#,Graphics,Gdi+,我以前没做过这个(看看它有多好),所以我显然很烂。在这里,当前鼠标位置周围的64个像素在窗体上绘制得稍大一些。问题是,它“有点”慢,我不知道从哪里开始修复 除此之外,我还制作了一个计时器线程,它在完成时不断调用更新图形和一些类似文本的fps,以显示绘制速度有多快 图像示例:(图像来自Microsoft VS2010中“IntelliTrace”中的字母“a”) 来源示例: using System; using System.Collections.Generic; using System.

我以前没做过这个(看看它有多好),所以我显然很烂。在这里,当前鼠标位置周围的64个像素在窗体上绘制得稍大一些。问题是,它“有点”慢,我不知道从哪里开始修复

除此之外,我还制作了一个计时器线程,它在完成时不断调用更新图形和一些类似文本的fps,以显示绘制速度有多快

图像示例:(图像来自Microsoft VS2010中“IntelliTrace”中的字母“a”)

来源示例:

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);
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
使用System.Runtime.InteropServices;
名称空间缩放
{
公共部分类Form1:Form
{
静态类dllRef
{
[DllImport(“user32.dll”)]
[返回:Marshallas(UnmanagedType.Bool)]
静态外部bool GetCursorPos(outpoint lpPoint);
[DllImport(“user32.dll”)]
静态外部IntPtr GetDC(IntPtr hwnd);
[DllImport(“user32.dll”)]
静态外部Int32释放DC(IntPtr hwnd、IntPtr hdc);
[DllImport(“gdi32.dll”)]
静态外部uint GetPixel(IntPtr hdc、intnxpos、intnypos);
//从http://www.pinvoke.net/default.aspx/gdi32/GetPixel.html
静态公共系统.Drawing.Color getPixelColor(int x,int y){
IntPtr hdc=GetDC(IntPtr.Zero);
uint pixel=GetPixel(hdc,x,y);
释放DC(IntPtr.Zero,hdc);
Color Color=Color.FromArgb((int)(像素&0x000000FF),
(整数)(像素和0x0000FF00)>>8,
(int)(像素&0x00FF0000)>>16);
返回颜色;
}
静态public System.Drawing.Point getMousePosition(){
点p=新点();
GetCursorPos(out p);
返回p;
}
}
公共表格1(){
初始化组件();
此尺寸=新尺寸(400400);
this.Text=“图像缩放”;
该位置=新点(640,0);
this.image=新位图(320320);
this.timeRef=DateTime.Now;
this.BackColor=Color.White;
定时器t=新定时器();
t、 间隔=25;
t、 Tick+=新的事件处理程序(计时器_Tick);
t、 Start();
}
公共无效计时器\u勾选(对象发送器、事件参数){
this.Form1_Paint(this,new PaintEventArgs(this.CreateGraphics(),new Rectangle(0,0,this.Width,this.Height));
}
private bool isdone=true;
私有整数iter=0;
私有位图图像;
私有日期时间timeRef;
私有void Form1_Paint(对象发送器、PaintEventArgs e){
中频(isdone){
isdone=false;
int步长=40;
点p=dllRef.getMousePosition();
Pen myPen=新笔(颜色:灰色,1);
SolidBrush myBrush=null;
位图图像2=新位图(320340);
Graphics gc=Graphics.FromImage(image2);
对于(int x=0;x<8;x++){
对于(int y=0;y<8;y++){
myBrush=新的SolidBrush(dllRef.getPixelColor(p.X-4+X,p.Y-4+Y));
gc.FillEllipse(myBrush,x*步,y*步,步骤-3,步骤-3);
gc.drawerlipse(myPen,x*步骤,y*步骤,步骤-3,步骤-3);
}
}
StringBuilder sb=新的StringBuilder();
某人(国际热核实验堆)
.Append(“中的帧”)
.Append(String.Format(“{0:0.######})”,((DateTime.Now this.timeRef.totalmillizes)/1000))
.附加(“s”);
gc.FillRectangle(新的SolidBrush(this.BackColor),新的矩形(0320320,40));
gc.DrawString(sb.ToString(),新字体(“Arial”,12),新SolidBrush(颜色.黑色),10320);
gc.Dispose();
isdone=true;
iter++;
图像=图像2;
}
e、 绘图图像(图像,35f,15f);
}
}
}
在我做了更改后,这一次大约快了98%:

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);
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
使用System.Runtime.InteropServices;
名称空间缩放
{
公共部分类Form1:Form
{
静态类dllRef
{
[DllImport(“user32.dll”)]
[返回:Marshallas(UnmanagedType.Bool)]
静态外部bool GetCursorPos(outpoint lpPoint);
[DllImport(“user32.dll”)]
静态外部IntPtr GetDC(IntPtr hwnd);
[DllImport(“user32.dll”)]
静态外部Int32释放DC(IntPtr hwnd、IntPtr hdc);
[DllImport(“gdi32.dll”)]
静态外部uint GetPixel(IntPtr hdc、intnxpos、intnypos);
//从http://www.pinvoke.net/default.aspx/gdi32/GetPixel.html
静态公共系统.Drawing.Color getPixelColor(int x,int y){
IntPtr hdc=GetDC(IntPtr.Zero);
uint pixel=GetPixel(hdc,x,y);
释放DC(IntPtr.Zero,hdc);
Color Color=Color.FromArgb((int)(像素&0x000000FF),
(整数)(像素和0x0000FF00)>>8,
(int)(像素&0x00FF0000)>>16);
返回颜色;
}
静态public System.Drawing.Point getMousePosition(){
点p=新点();
GetCursorPos(out p);
返回p;
}
}
for each pixel
  GetDC
  Read Pixel
  ReleaseDC
GetDC
for each pixel
  read pixel and store value
ReleaseDC