分层画图思想:如果背景不变,我们只需要在背景图的基础上画变化的部分,这就是提高效率的地方。
需要注意的地方:应该直接对picWork.CreateGraphics(),这样快。而不是picWork.Image =
btWork;
第一层指dxf,现在用上面的1/3的线填充来代替,这样能看出效率。第二层指坐标的网格线之类的,现在用中间的1/3的线填充来代替。变化的指的是目前正在画的线,还没有决定落点。
代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
// 分层画图的思想 by Kiseigo 2010.05.08. Help by wyz.
namespace LayerInGraphic
{
public
partial class FrmMain : Form
{
/// <summary>
/// 第一层背景,如dxf底图(不变)
/// </summary>
private Bitmap btBackGround1st;
/// <summary>
/// 第二层,如显示坐标的网格线(也可以理解为cad的第二个图层)
/// </summary>
private Bitmap btBackGround2nd;
/// <summary>
/// 这个可以不定义,因为它是比较慢的显示方式
/// </summary>
private Bitmap btWork;
/// <summary>
/// 第一层的画图对象
/// </summary>
private Graphics grapBkgrd1st;
/// <summary>
/// 第二层的画图对象
/// </summary>
private Graphics grapBkGrd2nd;
/// <summary>
/// 这个可以不定义,但是为了对比哪个是更快的显示方式,所以暂时不删除
/// </summary>
private Graphics grapWork;
/// <summary>
/// 直线的起点
/// </summary>
private Point ptStart = new Point(-1, -1);
/// <summary>
/// 鼠标移动时的画图次数
/// </summary>
private int countDraw = 0;
public FrmMain()
{
InitializeComponent();
}
private void FrmMain_Load(object sender, EventArgs e)
{
btBackGround1st = new Bitmap(picWork.Width, picWork.Height);
btBackGround2nd = new Bitmap(picWork.Width, picWork.Height);
btWork = new Bitmap(picWork.Width, picWork.Height);
grapBkgrd1st = Graphics.FromImage(btBackGround1st);
grapBkGrd2nd = Graphics.FromImage(btBackGround2nd);
grapWork = Graphics.FromImage(btWork);
// 画pic的上面1/3的部分。第一层。
for (int i = 0; i <= (int)(picWork.Height / 3);
i++)
{
grapBkgrd1st.DrawLine(Pens.Red, 0, i, picWork.Width, i);
}
grapBkGrd2nd.Clear(Color.White); //
没有这句的话,默认是透明,这样原来的线就一直添加,不会擦掉。
grapBkGrd2nd.DrawImage(btBackGround1st, 0, 0); //在第一层的基础上画第二层
// 画第二层。中间的1/3的屏幕。
for (int i = (int)(picWork.Height / 3); i <=
(int)(picWork.Height * 2.0 / 3); i++)
{
grapBkGrd2nd.DrawLine(Pens.Blue, 0, i, picWork.Width, i);
}
grapWork.DrawImage(btBackGround2nd, 0, 0);
// 显示前2层
picWork.Image = btBackGround2nd;
}
// 给起点赋值
private void picWork_MouseUp(object sender, MouseEventArgs e)
{
ptStart = new Point(e.X, e.Y);
}
// 鼠标移动时画线(当然,得先画前2层)
private void picWork_MouseMove(object sender, MouseEventArgs
e)
{
if (ptStart.X == -1)
{
return;
}
int tickCount = Environment.TickCount;
// 分层画图思想:如果背景不变,我们只需要在背景图的基础上画变化的部分,这就是提高效率的地方。
if (false) // 下面这种方式很慢,很不流畅。
{
grapWork.Clear(Color.White);
grapWork.DrawImage(btBackGround2nd, 0, 0);
grapWork.DrawLine(Pens.Black, ptStart, new Point(e.X, e.Y));
picWork.Image = btWork; // 可能是这里慢
}
else // 应该直接对picWork.CreateGraphics(),这样快
{
Graphics g = picWork.CreateGraphics();
g.DrawImage(btBackGround2nd, 0, 0);
g.DrawLine(Pens.Black, ptStart, new Point(e.X, e.Y));
g.Dispose();
}
countDraw++;
// 记录时间,以便研究效率,发现从屏幕左下移动到右下,画图80次左右,每次31ms左右。比较流畅。
File.AppendAllText(@"c:\tick.txt", countDraw.ToString() + " "
+
(Environment.TickCount - tickCount).ToString() + "\r\n");
}
}
}
加载中,请稍候......