做一个类似windows画图工具一样的东东,绘制直线、矩形之类的
拿绘制直线为例,鼠标左键按下时,移动鼠标开始绘制:
public partial class 画图 : Form
{
Graphics g1;
Point lastpoint;
enum PaintType { Pencil = 1, Line, Rectangle, Ellipse, Polygon};
PaintType painttype = PaintType.Pencil; ArrayList Path = new ArrayList(); //存放绘制路径
Pen mypen = new Pen(Color.Black); //画笔
GraphicsPath gp = new GraphicsPath();
public 画图()
{
InitializeComponent();
g1 = pictureBox1.CreateGraphics();
} private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
lastpoint = new Point(e.X, e.Y); //生成起点
} private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
//直线
if (painttype == PaintType.Line)
{
if (e.Button == MouseButtons.Left)
{
g1.Clear(Color.White); //清除上次绘制痕迹
Point currentpoint = new Point(e.X, e.Y);
g1.DrawLine(mypen, lastpoint, currentpoint); //绘制
gp.AddLine(lastpoint, currentpoint); //生成绘制路径
}
}
} private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
Path.Add(gp); //保存路径
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
foreach (GraphicsPath i in Path)
{
g1.DrawPath(mypen,i); //绘制所有保存的路径
}
}
}程序大概是这个样子,想法是用ArrayList保存从前绘制的路径,以便在每次Clear()清除后重绘画面,不然每次画完的线都会消失。但是这样写了没有效果。
小弟初学c#一个月,老师让做这个画图,快逼疯了!!!! 请高手指点迷津。
拿绘制直线为例,鼠标左键按下时,移动鼠标开始绘制:
public partial class 画图 : Form
{
Graphics g1;
Point lastpoint;
enum PaintType { Pencil = 1, Line, Rectangle, Ellipse, Polygon};
PaintType painttype = PaintType.Pencil; ArrayList Path = new ArrayList(); //存放绘制路径
Pen mypen = new Pen(Color.Black); //画笔
GraphicsPath gp = new GraphicsPath();
public 画图()
{
InitializeComponent();
g1 = pictureBox1.CreateGraphics();
} private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
lastpoint = new Point(e.X, e.Y); //生成起点
} private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
//直线
if (painttype == PaintType.Line)
{
if (e.Button == MouseButtons.Left)
{
g1.Clear(Color.White); //清除上次绘制痕迹
Point currentpoint = new Point(e.X, e.Y);
g1.DrawLine(mypen, lastpoint, currentpoint); //绘制
gp.AddLine(lastpoint, currentpoint); //生成绘制路径
}
}
} private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
Path.Add(gp); //保存路径
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
foreach (GraphicsPath i in Path)
{
g1.DrawPath(mypen,i); //绘制所有保存的路径
}
}
}程序大概是这个样子,想法是用ArrayList保存从前绘制的路径,以便在每次Clear()清除后重绘画面,不然每次画完的线都会消失。但是这样写了没有效果。
小弟初学c#一个月,老师让做这个画图,快逼疯了!!!! 请高手指点迷津。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;namespace WindowsApplication5
{
public partial class Form1 : Form
{
GraphicsPath gp = new GraphicsPath();
Point lastpoint;
Point currentpoint;
Pen mypen = new Pen(Color.Black);
public Form1()
{
InitializeComponent();
} Bitmap Cache1;
private void Form1_Load(object sender, EventArgs e)
{
Cache1 = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
Graphics g = Graphics.FromImage(Cache1);
g.Clear(Color.FromArgb(255,255,255));
g.Dispose();
} private void Form1_SizeChanged(object sender, EventArgs e)
{ } private void Form1_ClientSizeChanged(object sender, EventArgs e)
{
Cache1 = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
Graphics g = Graphics.FromImage(Cache1);
g.Clear(Color.FromArgb(255, 255, 255));
g.Dispose();
} private void Form1_MouseDown(object sender, MouseEventArgs e)
{
lastpoint = new Point(e.X, e.Y);
} private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
currentpoint = new Point(e.X, e.Y);
Graphics g=this.CreateGraphics();
g.DrawImageUnscaled(Cache1, 0, 0);
g.DrawLine(mypen, lastpoint, currentpoint);
g.Dispose();
}
} private void Form1_MouseUp(object sender, MouseEventArgs e)
{
gp.AddLine(lastpoint, currentpoint);
Graphics g = Graphics.FromImage(Cache1);
g.DrawPath(mypen, gp);
} private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImageUnscaled(Cache1,0,0);
}
}
}
拿着玩去吧...^_^
希望你参考我提供的思路来解决问题,直说了把继续用你的ArrayList...
主要绘制两部分,一部分是pictureBox中的Image,另一个是pictureBox
在pictureBox.Image中绘制的画面是不会消失的,看效果吧!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace WindowsApplication43
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 鼠标最后按下的位置
/// </summary>
Point lastPoint = Point.Empty; private enum PaintType { Pencil = 1, Line, Rectangle, Ellipse, Polygon };
PaintType paintType = PaintType.Pencil; private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
lastPoint = e.Location;
} private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
pictureBox1.Refresh();
Graphics vGraphics = Graphics.FromImage(pictureBox1.Image); // 直接绘制到Image中
switch (paintType)
{
case PaintType.Pencil:
break;
case PaintType.Line:
vGraphics.DrawLine(Pens.Black, lastPoint, e.Location);
break;
case PaintType.Ellipse:
vGraphics.DrawEllipse(Pens.Black, Rectangle.FromLTRB(
lastPoint.X, lastPoint.Y,
e.Location.X, e.Location.Y));
break;
case PaintType.Rectangle:
vGraphics.DrawRectangle(Pens.Black, Rectangle.FromLTRB(
lastPoint.X, lastPoint.Y,
e.Location.X, e.Location.Y));
break;
}
vGraphics.Dispose();
pictureBox1.Refresh();
lastPoint = Point.Empty;
} private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (lastPoint == Point.Empty) return; // 没有按下
pictureBox1.Refresh(); // 刷新界面
Graphics vGraphics = pictureBox1.CreateGraphics();
switch (paintType)
{
case PaintType.Pencil:
break;
case PaintType.Line:
vGraphics.DrawLine(Pens.Black, lastPoint, e.Location);
break;
case PaintType.Ellipse:
vGraphics.DrawEllipse(Pens.Black, Rectangle.FromLTRB(
lastPoint.X, lastPoint.Y,
e.Location.X, e.Location.Y));
break;
case PaintType.Rectangle:
vGraphics.DrawRectangle(Pens.Black, Rectangle.FromLTRB(
lastPoint.X, lastPoint.Y,
e.Location.X, e.Location.Y));
break;
}
vGraphics.Dispose();
} private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.Image = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics vGraphics = Graphics.FromImage(pictureBox1.Image);
vGraphics.FillRectangle(Brushes.White, vGraphics.ClipBounds);
vGraphics.Dispose(); int i = 0;
foreach (string vName in Enum.GetNames(typeof(PaintType)))
{
RadioButton vRadioButton = new RadioButton();
vRadioButton.Parent = this;
vRadioButton.Text = vName;
vRadioButton.Click += new EventHandler(radioButton_Click);
vRadioButton.Tag = Enum.GetValues(typeof(PaintType)).GetValue(i);
if (i == 0) vRadioButton.PerformClick(); // 默认选第一个
vRadioButton.Top = (i++) * 30;
}
} private void radioButton_Click(object sender, EventArgs e)
{
paintType = ((PaintType)((RadioButton)sender).Tag);
}
}
}
用链表保存位置信息是肯定没错的,只是全部重画会有闪烁的问题。