实验二:用winform实现画图
构造属于你的专属画图程序,可参考系统自带的绘图板
画布相当于一张纸,我们使用两张纸,一张originalimage用于保留最终绘图并贴在画板上;一张interimage用于保存中间绘图痕迹。
比如画一个矩形
选择颜色,判断改变颜色1还是颜色2
private void button_Click(object sender, EventArgs e)
{
Button currentButton = (Button)sender;
currentLabel.BackColor = currentButton.BackColor;
if(currentLabel==label1)
{
label1.BackColor = currentButton.BackColor;
color1 = currentButton.BackColor;
}
else
{
label7.BackColor = currentButton.BackColor;
color2 = currentButton.BackColor;
}
}
颜色1颜色2切换
方法:设置一个currentlabel指向当前颜色label
private void color1_Click(object sender, EventArgs e)
{
currentLabel = label1;
label3.BackColor = Color.PowderBlue;
label4.BackColor = Color.Transparent;
}
private void color2_Click(object sender, EventArgs e)
{
currentLabel = label7;
label4.BackColor = Color.PowderBlue;
label3.BackColor = Color.Transparent;
}
colordialog 调用颜色对话框,并将颜色添加到可用按钮中
重点:colorDialog1.ShowDialog()
private void makecolor_Click(object sender, EventArgs e)
{
if (colorDialog1.ShowDialog() == DialogResult.OK)
{
Color mycolor = colorDialog1.Color;
for (int i = 0; i < haveUse; i++)
{
if (allButton[i].BackColor == mycolor)//与第i个重复,则从第i+1个到num-1个都向前移动一格
{
for (int k = i; k < NUM - 1; k++)
{
allButton[k].BackColor = allButton[k + 1].BackColor;
}
haveUse--;
break;
}
}
if (haveUse == NUM)//已经满了,前移一格
{
for (int i = 0; i < NUM - 1; i++)
{
allButton[i] = allButton[i + 1];
}
allButton[NUM - 1].BackColor = mycolor;
haveUse++;
}
else//还没满
{
allButton[haveUse].BackColor = mycolor;
allButton[haveUse].Enabled = true;
haveUse++;
}
}
}
重点:绘制图形的函数
//使用Graphics对象实现
switch (type)
{
case "nonerh"://无填充菱形
{
PointF[] pointFs = { new PointF(leftX + width / 2, leftY), new PointF(leftX, leftY + height / 2), new PointF(leftX + width / 2, leftY + height), new PointF(leftX + width, leftY + height / 2) };
interGraphics.DrawPolygon(mypen, pointFs);
break;
}
case "solidrh"://纯色菱形
{
PointF[] pointFs = { new PointF(leftX + width / 2, leftY), new PointF(leftX, leftY + height / 2), new PointF(leftX + width / 2, leftY + height), new PointF(leftX + width, leftY + height / 2) };
interGraphics.FillPolygon(new SolidBrush(backcolor), pointFs);
interGraphics.DrawPolygon(mypen, pointFs);
break;
}
case "hatchrh"://圆点填充
{
PointF[] pointFs = { new PointF(leftX + width / 2, leftY), new PointF(leftX, leftY + height / 2), new PointF(leftX + width / 2, leftY + height), new PointF(leftX + width, leftY + height / 2) };
interGraphics.FillPolygon(new HatchBrush(HatchStyle.LargeConfetti, backcolor, Color.White), pointFs);
interGraphics.DrawPolygon(mypen, pointFs);
break;
}
case "nonetriangle"://无填充等腰三角形
{
PointF[] pointfs = { new PointF((startPoint.X + currentPoint.X) / 2, startPoint.Y), new PointF(startPoint.X, currentPoint.Y), currentPoint };
interGraphics.DrawPolygon(mypen, pointfs);
break;
}
case "solidtriangle"://纯色填充等腰三角形
{
PointF[] pointfs = { new PointF((startPoint.X + currentPoint.X) / 2, startPoint.Y), new PointF(startPoint.X, currentPoint.Y), currentPoint };
interGraphics.FillPolygon(new SolidBrush(backcolor), pointfs);
interGraphics.DrawPolygon(mypen, pointfs);
break;
}
case "hatchtriangle"://圆点填充等腰三角形
{
PointF[] pointfs = { new PointF((startPoint.X + currentPoint.X) / 2, startPoint.Y), new PointF(startPoint.X, currentPoint.Y), currentPoint };
interGraphics.FillPolygon(new HatchBrush(HatchStyle.LargeConfetti, backcolor, Color.White), pointfs);
interGraphics.DrawPolygon(mypen, pointfs);
break;
}
case "nonetriangle2"://无填充直角三角形
{
PointF[] pointfs = { startPoint, new PointF(startPoint.X, currentPoint.Y), currentPoint };
interGraphics.DrawPolygon(mypen, pointfs);
break;
}
case "solidtriangle2"://纯色填充直角三角形
{
PointF[] pointfs = { startPoint, new PointF(startPoint.X, currentPoint.Y), currentPoint };
interGraphics.FillPolygon(new SolidBrush(backcolor), pointfs);
interGraphics.DrawPolygon(mypen, pointfs);
break;
}
case "hatchtriangle2"://圆点填充直角三角形
{
PointF[] pointfs = {startPoint, new PointF(startPoint.X, currentPoint.Y), currentPoint };
interGraphics.FillPolygon(new HatchBrush(HatchStyle.LargeConfetti, backcolor, Color.White), pointfs);
interGraphics.DrawPolygon(mypen, pointfs);
break;
}
case "noneline"://直线
interGraphics.DrawLine(mypen, startPoint, currentPoint);
break;
case "nonerectangle"://无填充矩形
interGraphics.DrawRectangle(mypen, leftX, leftY, width, height);
break;
case "noneellipse"://无填充椭圆
{
interGraphics.DrawEllipse(mypen, leftX, leftY, width, height);
break;
}
case "nonearc"://弧线
{
if (width != 0 && height != 0)
interGraphics.DrawArc(mypen, leftX, leftY, width, height, 0, 180);
break;
}
case "nonepie"://无填充饼形
{
if (width != 0 && height != 0)
interGraphics.DrawPie(mypen, leftX, leftY, width, height, 0, 180);
break;
}
case "solidrectangle"://纯色填充矩形
{
interGraphics.FillRectangle(new SolidBrush(backcolor), leftX, leftY, width, height);
interGraphics.DrawRectangle(mypen, leftX, leftY, width, height);
break;
}
case "solidellipse"://纯色填充椭圆
{
interGraphics.FillEllipse(new SolidBrush(backcolor), leftX, leftY, width, height);
interGraphics.DrawEllipse(mypen, leftX, leftY, width, height);
break;
}
case "solidpie"://纯色填充饼形
{
if (width != 0 && height != 0)
{
interGraphics.FillPie(new SolidBrush(backcolor), leftX, leftY, width, height, 0, 180);
interGraphics.DrawPie(mypen, leftX, leftY, width, height, 0, 180);
}
break;
}
case "hatchrectangle"://圆点填充矩形
{
interGraphics.FillRectangle(new HatchBrush(HatchStyle.LargeConfetti,backcolor,Color.White), leftX, leftY, width, height);
interGraphics.DrawRectangle(mypen, leftX, leftY, width, height);
break;
}
case "hatchellipse"://圆点填充椭圆
{
interGraphics.FillEllipse(new HatchBrush(HatchStyle.LargeConfetti,backcolor,Color.White), leftX, leftY, width, height);
interGraphics.DrawEllipse(mypen, leftX, leftY, width, height);
break;
}
case "hatchpie"://圆点填充饼形
{
if (width != 0 && height != 0)
{
interGraphics.FillPie(new HatchBrush(HatchStyle.LargeConfetti, backcolor,Color.White), leftX, leftY, width, height, 0, 180);
interGraphics.DrawPie(mypen, leftX, leftY, width, height, 0, 180);
}
break;
}
}
方法:使用DrawLine画线方法 从startpoint 到 currentpoint
public void Pencile(MouseEventArgs e)//铅笔
{
PointF currentPoint = new PointF(e.X-10, e.Y+8);
Graphics interGraphics = Graphics.FromImage(interImg);
interGraphics.DrawLine(mypen, startPoint,currentPoint);
originalImg = (Image)interImg.Clone();
targetGraphics.DrawImage(originalImg,0,0);
startPoint = currentPoint;
}
方法:相当于用纯色矩形覆盖,用DrwaRectangle方法
public void Eraser(MouseEventArgs e)//橡皮擦
{
PointF currentPoint = new PointF(e.X, e.Y);
Graphics interGraphics = Graphics.FromImage(interImg);
interGraphics.FillRectangle(new SolidBrush(backcolor), startPoint.X-5,startPoint.Y-5,16,10);
originalImg = (Image)interImg.Clone();
targetGraphics.DrawImage(originalImg, 0, 0);
startPoint = currentPoint;
}
粗细:设置pen的Width属性
线条:设置pen的DashStyle属性。实现为Solid,虚线为Dot
填充:无填充:使用pen画;纯色填充:先用SolidBrush笔刷画,再用pen画上边;圆点填充:先用HatchBrush笔刷(设置属性HatchStyle.LargeConfetti)画,再用pen画上边
使用TextBox,点击绘图板,当绘图板里没有文本框时,显示文本框;有文本框时,移除文本框并将文本框的文字绘到绘图板上
重点:
动态添加控件:panel10.Controls.Add(mytb);(panel0为父容器)
动态删除控件:panel10.Controls.Remove(control);
绘制文字:interGraphics.DrawString(str, font, brush,pointF);
font为字体样式,brush为字体填充笔刷,pointF为字体在父容器中的相对位置。
if (drawtype == "text")
{
if (Extentionclass.FindControl(panel10, "mytb") == null)//第一次按下
{
TextBox mytb = new TextBox();
mytb.Name = "mytb";
mytb.Location = new Point(e.X, e.Y+pictureBox1.Location.Y);//位置
mytb.BorderStyle = BorderStyle.FixedSingle;
panel10.Controls.Add(mytb);
// panel10.Controls.SetChildIndex(mytb, 100);
mytb.BringToFront();
}
else
{
Control control = Extentionclass.FindControl(panel10, "mytb");
string str =control.Text;
Font font = new Font("宋体", 9);
Brush brush = new SolidBrush(userControl11.Color1);
PointF pointF = new PointF(control.Location.X, control.Location.Y - pictureBox1.Location.Y);
panel10.Controls.Remove(control);
Graphics interGraphics = Graphics.FromImage(tool.InterImage);
interGraphics.DrawString(str, font, brush,pointF);
graphics.DrawImage(tool.InterImage, 0, 0);
}
}
新建文件之前要判断是否保存文件
用到的方法:
消息提示框:MessageBox.Show(“是否要保存文件”, “系统提示”, MessageBoxButtons.YesNoCancel);
保存、另存为、新建文件:如下代码
新建时要初始化绘画板
private void 新建ToolStripMenuItem_Click(object sender, EventArgs e)
{
//是否保存
DialogResult dialogResult = MessageBox.Show("是否要保存文件", "系统提示", MessageBoxButtons.YesNoCancel);
if (dialogResult==DialogResult.Yes)//选择先保存
{
if (sFilename != null)//可以直接保存
{
if (MessageBox.Show("是否要保存文件?", "系统提示", MessageBoxButtons.YesNo) == DialogResult.Yes)//选择yes保存
{
tool.OriginalImage.Save(sFilename);
}
}
else
{
SaveFileDialog saveFile = new SaveFileDialog();
// saveFile.FileName = "";
saveFile.Filter = "JPG|*.jpg;*.jpeg;*.jpe;*.jfif|GIF|*.gif|PNG|*.png|TIF|*.tif;*.tiff|ICO|*.ico|所有文件|*.*";
if (saveFile.ShowDialog() == DialogResult.OK)//文件夹显示成功
{
sFilename = saveFile.FileName;
tool.OriginalImage.Save(sFilename);
}
}
}
else if(dialogResult==DialogResult.Cancel)//取消则什么都不做直接返回
{
return;
}
//
//新建
Bitmap bmap= new Bitmap(pictureBox1.Size.Width, pictureBox1.Size.Height);
Graphics g = Graphics.FromImage(bmap);
g.FillRectangle(new SolidBrush(Color.White), 0, 0, bmap.Width, bmap.Height);
g.Dispose();
tool.targetGraphics.DrawImage(bmap,0,0);
tool.OriginalImage = bmap;
bmap.Dispose();
}
打开之前要提示是否保存文件
OpenFileDialog openFile = new OpenFileDialog();
openFile.FileName = "";
openFile.Filter = "JPG|*.jpg;*.jpeg;*.jpe;*.jfif|GIF|*.gif|PNG|*.png|TIF|*.tif;*.tiff|ICO|*.ico|所有文件|*.*";
if (openFile.ShowDialog() == DialogResult.OK)//文件夹显示ok(成功)
{
if(openFile.FileName!="")
{
//插入是否保存代码
Bitmap bitmap = new Bitmap(openFile.FileName);//从指定的文件初始化bitmap
pictureBox1.Size = bitmap.Size;//调整绘图区大小为图片大小
pictureBox3.Location = new Point(pictureBox1.Width, pictureBox1.Height + pictureBox1.Location.Y);
//改变那个小角角的大小
Bitmap bm = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(bm);
g.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height));
g.DrawImage(bitmap, 0, 0);
g.Dispose();
tool.targetGraphics = pictureBox1.CreateGraphics();
tool.targetGraphics.DrawImage(bm, 0, 0);
tool.OriginalImage = bm;
bitmap.Dispose();
bm.Dispose();
sFilename = openFile.FileName;
openFile.Dispose();
}
}
}
方法:绘制一个和画板一样大小的白色矩形,注意要更新原始画布和中间画布
private void 清除ToolStripMenuItem_Click(object sender, EventArgs e)
{
Bitmap newpic = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(newpic);
g.FillRectangle(new SolidBrush(Color.White), 0, 0,pictureBox1.Width, pictureBox1.Height);
g.Dispose();
g = pictureBox1.CreateGraphics();
g.DrawImage(newpic, 0, 0);
g.Dispose();
tool.OriginalImage = newpic;
}
点击Form右上角的关闭角标时调用Form1_FormClosing方法
点击菜单项的关闭选项时用this.close()
关闭前要提示是否保存
改变画板大小通过画板右下角的一个小pictruebox(pb)实现。移动pb改变pb的位置,根据pb的相对于父容器的位置(即location)及画板的location得到画板的大小,改变画板大小后要改变初始画布和中间画布的大小,并将画布重新贴在画板上才能显示图案。
private bool isResize = false;
private void pictureBox3_MouseDown(object sender, MouseEventArgs e)
{
isResize = true;
}
private void pictureBox3_MouseMove(object sender, MouseEventArgs e)
{
if (isResize)
{
pictureBox3.Location = new Point(pictureBox3.Location.X + e.X, pictureBox3.Location.Y + e.Y);
}
}
private void pictureBox3_MouseUp(object sender, MouseEventArgs e)
{
isResize = false;
pictureBox1.Size = new Size(pictureBox3.Location.X-pictureBox1.Location.X, pictureBox3.Location.Y-pictureBox1.Location.Y);//改变大小
tool.targetGraphics = pictureBox1.CreateGraphics();//再次设置
Bitmap newBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics tempGraphic = Graphics.FromImage(newBitmap);
tempGraphic.FillRectangle(new SolidBrush(Color.White), 0, 0, pictureBox1.Width, pictureBox1.Height);//创建一张新的临时画纸
tempGraphic.DrawImage(tool.OriginalImage, 0, 0);//将original画在上面
tempGraphic.Dispose();
// graphics = pictureBox1.CreateGraphics();
//tempGraphic =pictureBox1.CreateGraphics();
//tempGraphic.DrawImage(newBitmap, 0, 0);
//tempGraphic.Dispose();
// tool.targetGraphics.DrawImage(newBitmap, 0, 0);//--为什么不能重绘绘图板
tool.OriginalImage = newBitmap;
newBitmap.Dispose();
}
右击解决方案里的项目->进入属性->找到左侧的资源->将图像导入其中->找到按钮的image属性导入图片
进入该项目的项目文件夹->进入bin文件夹->进入debug文件夹->在debug文件夹中创建一个文件夹存放.ico或者.cur图片
相应代码如下:
pictureBox1.Cursor = new Cursor(Application.StartupPath + @"\img\pen.ico");
在改变绘图板的大小,或者绘图板被覆盖之后要调用重绘绘图板方法才能显示图像
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.DrawImage(tool.OriginalImage, 0, 0);
}