前言
该画笔程序是自己制作的一个小程序,功能基本完善,但是与专业软件还是存在着一定差距的。该软件具有画直线、矩形、正方形、椭圆、圆、徒手画(随意画)、屏幕写字、屏幕画笔(截屏后在截图上作图)、停止绘图、撤销、重做、设置线宽、设置颜色、放大、缩小、文件另存为(保存)、作图保存为图片、保存用户设置等功能。
界面效果图
部分代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//添加命名空间
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Windows.Forms;
namespace MyPencil
{
//绘图枚举类型
public enum DrawType
{
Stop = 0, Line = 1, Rectangle = 2, Circle = 3, Ellipse = 4, Square = 5, Sketch = 6, Writing = 7
}
//图形(Shape)抽象基类
public abstract class Shape
{
//类字段
private int _penWidth = 10; //画笔线宽
private Color _penColor = Color.Red; //画笔颜色
//类属性
public int _PenWidth { get => _penWidth; set => _penWidth = value; } //画笔线宽
public Color _PenColor { get => _penColor; set => _penColor = value; } //画笔颜色
//绘制图元方法(抽象方法)
public abstract void Draw(Graphics g, DashStyle ds, double zoomRatio);
//写入文件方法(抽象方法)
public abstract void Write(BinaryWriter bw);
//读取文件方法(抽象方法)
public abstract void Read(BinaryReader br);
}
//直线(Line)子类
public class Line : Shape
{
//类字段
private Point _p1;//直线的起点
private Point _p2;//直线的终点
//类属性
public Point _P1 { get => _p1; set => _p1 = value; }//直线的起点
public Point _P2 { get => _p2; set => _p2 = value; }//直线的终点
//构造方法1
public Line()
{
}
//构造方法2
public Line(Point p1, Point p2)
{
_p1 = p1;
_p2 = p2;
}
//绘制图元方法(覆盖基类抽象方法)
public override void Draw(Graphics g, DashStyle ds, double zoomRatio)
{
//创建画笔对象
Pen pen = new Pen(_PenColor, (int)(_PenWidth * zoomRatio));
//设置画笔线型
pen.DashStyle = ds;
//获取缩放后的直线的起点、终点坐标
Point p1 = new Point((int)(_p1.X * zoomRatio), (int)(_p1.Y * zoomRatio));
Point p2 = new Point((int)(_p2.X * zoomRatio), (int)(_p2.Y * zoomRatio));
//绘制直线
g.DrawLine(pen, p1, p2);
}
//写入文件方法(覆盖抽象方法)
public override void Write(BinaryWriter bw)
{
//写入线宽和颜色
bw.Write(_PenWidth);
bw.Write(_PenColor.ToArgb());
//写入_p1点和_p2点的坐标
bw.Write(_p1.X); bw.Write(_p1.Y);
bw.Write(_p2.X); bw.Write(_p2.Y);
}
//读取文件方法(覆盖抽象方法)
public override void Read(BinaryReader br)
{
//读出线宽和颜色
_PenWidth = br.ReadInt32();
_PenColor = Color.FromArgb(br.ReadInt32());
//读出_p1点和_p2点的坐标
_p1.X = br.ReadInt32(); _p1.Y = br.ReadInt32();
_p2.X = br.ReadInt32(); _p2.Y = br.ReadInt32();
}
}
//矩形(Rectangle)子类
public class Rectangle :Shape
{
//类字段
private Point _p1;//矩形对角线的第一个点
private Point _p2;//矩形对角线的第二个点
//类属性
public Point _P1 { get => _p1; set => _p1 = value; }//矩形对角线的第一个点
public Point _P2 { get => _p2; set => _p2 = value; }//矩形对角线的第二个点
//构造方法1
public Rectangle()
{
}
//构造方法2
public Rectangle(Point p1, Point p2)
{
_p1 = p1;
_p2 = p2;
}
//绘制图元方法(覆盖基类抽象方法)
public override void Draw(Graphics g, DashStyle ds, double zoomRatio)
{
//创建画笔对象
Pen pen = new Pen(_PenColor, (int)(_PenWidth * zoomRatio));
//设置画笔线型
pen.DashStyle = ds;
//获取缩放后矩形对角线点的坐标
Point p1 = new Point((int)(_p1.X * zoomRatio), (int)(_p1.Y * zoomRatio));
Point p2 = new Point((int)(_p2.X * zoomRatio), (int)(_p2.Y * zoomRatio));
//获取矩形左上角坐标
Point leftTop = new Point();
leftTop.X = (p1.X <= p2.X) ? p1.X : p2.X;
leftTop.Y = (p1.Y <= p2.Y) ? p1.Y : p2.Y;
//绘制矩形
g.DrawRectangle(pen, leftTop.X, leftTop.Y, Math.Abs(p2.X - p1.X), Math.Abs(p2.Y - p1.Y));
}
//写入文件方法(覆盖抽象方法)
public override void Write(BinaryWriter bw)
{
//写入线宽和颜色
bw.Write(_PenWidth);
bw.Write(_PenColor.ToArgb());
//写入_p1点和_p2点的坐标
bw.Write(_p1.X); bw.Write(_p1.Y);
bw.Write(_p2.X); bw.Write(_p2.Y);
}
//读取文件方法(覆盖抽象方法)
public override void Read(BinaryReader br)
{
//读出线宽和颜色
_PenWidth = br.ReadInt32();
_PenColor = Color.FromArgb(br.ReadInt32());
//读出_p1点和_p2点的坐标
_p1.X = br.ReadInt32(); _p1.Y = br.ReadInt32();
_p2.X = br.ReadInt32(); _p2.Y = br.ReadInt32();
}
}
//正方形(Square)子类
public class Square : Shape
{
//类字段
private Point _p1;//正方形对角线的第一个点
private Point _p2;//正方形对角线的第二个点
//类属性
public Point _P1 { get => _p1; set => _p1 = value; }//正方形对角线的第一个点
public Point _P2 { get => _p2; set => _p2 = value; }//正方形对角线的第二个点
//构造方法1
public Square()
{
}
//构造方法2
public Square(Point p1, Point p2)
{
_p1 = p1;
_p2 = p2;
}
//绘制图元方法(覆盖基类抽象方法)
public override void Draw(Graphics g, DashStyle ds, double zoomRatio)
{
//创建画笔对象
Pen pen = new Pen(_PenColor, (int)(_PenWidth * zoomRatio));
//设置画笔线型
pen.DashStyle = ds;
//获取缩放后正方形对角线点的坐标
Point p1 = new Point((int)(_p1.X * zoomRatio), (int)(_p1.Y * zoomRatio));
Point p2 = new Point((int)(_p2.X * zoomRatio), (int)(_p2.Y * zoomRatio));
//得到正方形的边长
float length = (float)(Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2)) / Math.Sqrt(2));
//正方形的固定点
Point stablePoint = new Point();
//固定点在左上角
if(p1.X <= p2.X && p1.Y <= p2.Y)
{
stablePoint.X = p1.X;
stablePoint.Y = p1.Y;
}
//固定点在左下角
else if(p1.X <= p2.X && p1.Y >= p2.Y)
{
stablePoint.X = p1.X;
stablePoint.Y = (int)(p1.Y - length);
}
//固定点在右上角
else if(p1.X >= p2.X && p1.Y <= p2.Y)
{
stablePoint.X = (int)(p1.X - length);
stablePoint.Y = p1.Y;
}
//固定点在右下角
else
{
stablePoint.X = (int)(p1.X - length);
stablePoint.Y = (int)(p1.Y - length);
}
//绘制正方形
g.DrawRectangle(pen, stablePoint.X, stablePoint.Y, length, length) ;
}
//写入文件方法(覆盖抽象方法)
public override void Write(BinaryWriter bw)
{
//写入线宽和颜色
bw.Write(_PenWidth);
bw.Write(_PenColor.ToArgb());
//写入_p1点和_p2点的坐标
bw.Write(_p1.X); bw.Write(_p1.Y);
bw.Write(_p2.X); bw.Write(_p2.Y);
}
//读取文件方法(覆盖抽象方法)
public override void Read(BinaryReader br)
{
//读出线宽和颜色
_PenWidth = br.ReadInt32();
_PenColor = Color.FromArgb(br.ReadInt32());
//读出_p1点和_p2点的坐标
_p1.X = br.ReadInt32(); _p1.Y = br.ReadInt32();
_p2.X = br.ReadInt32(); _p2.Y = br.ReadInt32();
}
}
//圆形(Circle)子类
public class Circle:Shape
{
//类字段
private Point _pCenter;//圆的中心点;
private float _r;//圆的半径
//构造方法1
public Circle()
{
}
//构造方法2
public Circle(Point pCenter, float r)
{
_pCenter = pCenter;
_r = r;
}
//类属性
public Point _PCenter { get => _pCenter; set => _pCenter = value; }//圆的中心点;
public float _R { get => _r; set => _r = value; }//圆的半径
//绘制图元方法(覆盖基类抽象方法)
public override void Draw(Graphics g, DashStyle ds, double zoomRatio)
{
//创建画笔对象
Pen pen = new Pen(_PenColor, (int)(_PenWidth * zoomRatio));
//设置画笔线型
pen.DashStyle = ds;
//获取缩放后的圆心坐标
Point pCenter = new Point((int)(_pCenter.X * zoomRatio), (int)(_pCenter.Y * zoomRatio));
//获取缩放后的半径
float r = (float)(_r * zoomRatio);
//绘制圆
g.DrawEllipse(pen, pCenter.X - r, pCenter.Y - r, 2 * r, 2 * r);
}
//写入文件方法(覆盖抽象方法)
public override void Write(BinaryWriter bw)
{
//写入线宽和颜色
bw.Write(_PenWidth);
bw.Write(_PenColor.ToArgb());
//写入中心点坐标和半径
bw.Write(_pCenter.X);
bw.Write(_pCenter.Y);
bw.Write(_r);
}
//读取文件方法(覆盖抽象方法)
public override void Read(BinaryReader br)
{
//读出线宽和颜色
_PenWidth = br.ReadInt32();
_PenColor = Color.FromArgb(br.ReadInt32());
//读出中心点坐标和半径
_pCenter.X = br.ReadInt32();
_pCenter.Y = br.ReadInt32();
_r = br.ReadSingle();
}
}
//椭圆(ellipse)子类
public class Ellipse :Shape
{
//类字段
private Point _pCenter;//椭圆的中心点;
private float _halfR;//椭圆的半短轴
//构造方法1
public Ellipse()
{
}
//构造方法2
public Ellipse(Point pCenter, float halfR)
{
_pCenter = pCenter;
_halfR = halfR;
}
//类属性
public Point _PCenter { get => _pCenter; set => _pCenter = value; }//椭圆的中心点;
public float _HalfR { get => _halfR; set => _halfR = value; }//椭圆的半短轴
//绘制图元方法(覆盖基类抽象方法)
public override void Draw(Graphics g, DashStyle ds, double zoomRatio)
{
//创建画笔对象
Pen pen = new Pen(_PenColor, (int)(_PenWidth * zoomRatio));
//设置画笔线型
pen.DashStyle = ds;
//获取缩放后的圆心坐标
Point pCenter = new Point((int)(_pCenter.X * zoomRatio), (int)(_pCenter.Y * zoomRatio));
//获取缩放后的半径
float halfR = (float)(_halfR * zoomRatio);
//绘制椭圆
g.DrawEllipse(pen, pCenter.X - halfR, pCenter.Y - halfR, 2 * halfR, 3 * halfR);
}
//写入文件方法(覆盖抽象方法)
public override void Write(BinaryWriter bw)
{
//写入线宽和颜色
bw.Write(_PenWidth);
bw.Write(_PenColor.ToArgb());
//写入中心点坐标和半径
bw.Write(_pCenter.X);
bw.Write(_pCenter.Y);
bw.Write(_halfR);
}
//读取文件方法(覆盖抽象方法)
public override void Read(BinaryReader br)
{
//读出线宽和颜色
_PenWidth = br.ReadInt32();
_PenColor = Color.FromArgb(br.ReadInt32());
//读出中心点坐标和半径
_pCenter.X = br.ReadInt32();
_pCenter.Y = br.ReadInt32();
_halfR = br.ReadSingle();
}
}
//草图(Sketch)子类
public class Sketch : Shape
{
//草图的所有点
private List<Point> _pointList = new List<Point>();
//类属性
public List<Point> _PointList
{
get { return _pointList; }
set { _pointList = value; }
}
//构造方法
public Sketch()
{
}
//绘制图元方法(覆盖抽象方法)
public override void Draw(Graphics g, DashStyle ds, double zoomRatio)
{
//创建画笔对象
Pen pen = new Pen(_PenColor, (int)(_PenWidth * zoomRatio));
//设置画笔类型
pen.DashStyle = ds;
//设置画笔的线帽样式
pen.StartCap = LineCap.Round;
pen.EndCap = LineCap.Round;
pen.LineJoin = LineJoin.Round;
g.SmoothingMode = SmoothingMode.AntiAlias;//抗锯齿
//绘制Sketch的所有直线段
for (int i = 1; i <= _pointList.Count - 1; i++)
{
//Point p1 = new Point((int)(_pointList[i - 1].X * zoomRatio), (int)(_pointList[i - 1].Y * zoomRatio));
//Point p2 = new Point((int)(_pointList[i].X * zoomRatio), (int)(_pointList[i].Y * zoomRatio));
//g.DrawLine(pen, p1, p2);
//创建一个临时列表,用于存储放大后的点坐标
List<Point> tempList = new List<Point>();
foreach (Point point in _pointList)
tempList.Add(new Point((int)(point.X * zoomRatio), ((int)(point.Y * zoomRatio))));
g.DrawCurve(pen, tempList.ToArray());
}
}
//写入文件方法(覆盖抽象方法)
public override void Write(BinaryWriter binaryWriter)
{
//写入线宽和颜色
binaryWriter.Write(_PenWidth);
binaryWriter.Write(_PenColor.ToArgb());
//写入Sketch的点总数
binaryWriter.Write(_pointList.Count());
//逐一写入Sketch的点坐标
foreach (Point tempPoint in _pointList)
{
binaryWriter.Write(tempPoint.X);
binaryWriter.Write(tempPoint.Y);
}
}
//读取文件方法(覆盖抽象方法)
public override void Read(BinaryReader binaryReader)
{
//清空_pointList
_pointList.Clear();
//读出线宽和颜色
_PenWidth = binaryReader.ReadInt32();
_PenColor = Color.FromArgb(binaryReader.ReadInt32());
//读出Sketch的点总数
int pointCount = binaryReader.ReadInt32();
//逐一读出各点的坐标,并添加到_pointList
for (int i = 0; i <= pointCount - 1; i++)
{
int x = binaryReader.ReadInt32();
int y = binaryReader.ReadInt32();
Point point = new Point(x, y);
_pointList.Add(point);
}
}
}
//屏幕写字(WritingFont)子类
public class WritingFont : Shape
{
//字体的样式和大小,类字段
private Font _fontStyleSize;
//字, 类字段
private string _fontText;
//字的坐标,类字段
private Point _fontLocation;
public Font _FontStyleSize { get => _fontStyleSize; set => _fontStyleSize = value; }//类属性
public string _FontText { get => _fontText; set => _fontText = value; }//类属性
public Point _FontLocation { get => _fontLocation; set => _fontLocation = value; }//类属性
//构造方法
public WritingFont()
{
}
//绘制图元方法(覆盖抽象方法)
public override void Draw(Graphics g, DashStyle ds, double zoomRatio)
{
//绘制字体
g.DrawString(_fontText, _fontStyleSize, new SolidBrush(_PenColor), (int)(_fontLocation.X * zoomRatio), (int)(_fontLocation.Y * zoomRatio));
}
//写入文件方法(覆盖抽象方法)
public override void Write(BinaryWriter binaryWriter)
{
//写入大小、样式、颜色、坐标、内容
binaryWriter.Write((int)(_fontStyleSize.Size));
binaryWriter.Write(_fontStyleSize.FontFamily.Name.ToString());
binaryWriter.Write(_PenColor.ToArgb());
binaryWriter.Write(_fontLocation.X);
binaryWriter.Write(_fontLocation.Y);
binaryWriter.Write(_fontText.ToString());
}
//读取文件方法(覆盖抽象方法)
public override void Read(BinaryReader binaryReader)
{
//读取大小、样式、颜色、坐标、内容
int size = binaryReader.ReadInt32();
string name = binaryReader.ReadString();
_fontStyleSize = new Font(name, size, FontStyle.Regular);
_PenColor = Color.FromArgb(binaryReader.ReadInt32());
_fontLocation.X = binaryReader.ReadInt32();
_fontLocation.Y = binaryReader.ReadInt32();
_fontText = binaryReader.ReadString();
}
}
}