目录
C# Windows Forms上绘制画板:
详细解释:
TempData临时数据,用来保存画笔相关的信息,如:颜色,大小,坐标等
类声明和成员变量
构造函数
文件菜单项点击事件
保存菜单项点击事件
画笔大小选择
颜色选择
清空画布
鼠标事件处理
完整代码:
总结

详细解释:
TempData临时数据,用来保存画笔相关的信息,如:颜色,大小,坐标等
public static class TempData
{
    /// <summary>
    /// 用来保存上一次坐标点
    /// </summary>
    public static Point PrevPoint { get; set; }
    /// <summary>
    /// 画笔的颜色
    /// </summary>
    public static Color PenColor { get; set; } = Color.Black;
    /// <summary>
    /// 画笔的粗细
    /// </summary>
    public static int PenWidth { get; set; } = 2;
    
}类声明和成员变量
- Form1类继承自- Form,表示一个Windows表单。
- paintStart是一个布尔变量,用于跟踪鼠标是否按下,从而开始绘图。
- g是一个- Graphics对象,用于在窗体控件上绘制图像。
- bmp是一个- Bitmap对象,用作绘图的画布。- public partial class Form1 : Form { bool paintStart = false; // 标识是否开始绘画 Graphics g = null; // 用于绘制图形的Graphics对象 Bitmap bmp = null; // 用于存储绘制内容的Bitmap对象
构造函数
- InitializeComponent方法用于初始化窗体上的控件。
- g被初始化为- panel2的- Graphics对象。
- bmp被初始化为一个与- panel2控件大小相同的- Bitmap对象。- public Form1() { InitializeComponent(); g = panel2.CreateGraphics(); bmp = new Bitmap(panel2.Width, panel2.Height); }
文件菜单项点击事件
- 打开一个文件对话框,让用户选择一个JPG图片文件。
- 如果用户选择了文件并点击了OK,当前的 Bitmap对象bmp被替换为用户选择的图片。
- 使用 Graphics对象g将新的Bitmap绘制到panel2上。private void 文件FToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); dlg.Filter = "图片(*.jpg)|*.JPG"; if (dlg.ShowDialog() == DialogResult.OK) { bmp = new Bitmap(dlg.FileName); g.DrawImage(bmp, new Point(0, 0)); } }
保存菜单项点击事件
- 打开一个保存文件对话框,让用户选择保存路径和文件名。
- 如果用户选择了路径并点击了OK,尝试将当前的 Bitmap对象bmp保存为JPG图片。
- 如果保存过程中发生异常(例如文件被其他程序占用),显示一个错误消息。 private void 保存SToolStripMenuItem_Click(object sender, EventArgs e) { SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.Filter = "图片(*.jpg)|*.JPG"; if (saveFileDialog.ShowDialog() == DialogResult.OK) { try { bmp.Save(saveFileDialog.FileName); } catch (Exception) { MessageBox.Show("保存的文件名称,已经被独占打开!重新输入新文件名!"); } } }
画笔大小选择
- 这些方法设置画笔的大小,TempData.PenWidth存储当前选择的画笔宽度。private void 小号画笔ToolStripMenuItem_Click(object sender, EventArgs e) { TempData.PenWidth = 2; } private void 中号画笔ToolStripMenuItem_Click(object sender, EventArgs e) { TempData.PenWidth = 6; } private void 大号画笔ToolStripMenuItem_Click(object sender, EventArgs e) { TempData.PenWidth = 10; }
颜色选择
- 打开一个颜色对话框,让用户选择画笔的颜色。
- 如果用户选择了颜色并点击了OK,将选择的颜色存储在 TempData.PenColor中。清空画布private void 颜色ToolStripMenuItem_Click(object sender, EventArgs e) { ColorDialog colorDialog = new ColorDialog(); if (colorDialog.ShowDialog() == DialogResult.OK) { TempData.PenColor = colorDialog.Color; } }
清空画布
- 显示一个确认对话框,询问用户是否确定要清空画布。
- 如果用户点击“Yes”,清空 panel2的内容,重新创建一个空白的Bitmap对象,并将其绘制到panel2上。private void 清空ToolStripMenuItem_Click(object sender, EventArgs e) { DialogResult dr = MessageBox.Show("你确定要清空吗?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dr == DialogResult.Yes) { g.Clear(Color.White); bmp = new Bitmap(panel2.Width, panel2.Height); g.DrawImage(bmp, new Point(0, 0)); } }
鼠标事件处理
- MouseDown: 当用户在- panel2上按下鼠标左键时,设置- paintStart为- true并记录当前鼠标位置。
- MouseMove: 当用户在- panel2上移动鼠标时,如果- paintStart为- true,则根据选择的工具(画笔或橡皮擦)绘制线条或擦除区域。
- MouseUp: 当用户在- panel2上释放鼠标左键时,设置- paintStart为- false,停止绘图。- private void panel2_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { paintStart = true; TempData.PrevPoint = new Point(e.X, e.Y); } } private void panel2_MouseMove(object sender, MouseEventArgs e) { Graphics g2 = Graphics.FromImage(bmp); Pen pen = new Pen(TempData.PenColor, TempData.PenWidth); Point pt2 = new Point(e.X, e.Y); if (rbPen.Checked && paintStart) { g2.DrawLine(pen, TempData.PrevPoint, pt2); TempData.PrevPoint = pt2; g.DrawImage(bmp, 0, 0); } else if (rbEraser.Checked && paintStart) { g2.FillRectangle(new SolidBrush(panel2.BackColor), e.X, e.Y, TempData.PenWidth + 50, TempData.PenWidth + 50); g.DrawImage(bmp, 0, 0); } } private void panel2_MouseUp(object sender, MouseEventArgs e) { paintStart = false; }
完整代码:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace _2.画板
{
    public partial class Form1 : Form
    {
        // 标识,表示是否开始绘画
        bool paintStart = false;
        // 画板1(用panel2创建的,主要用来显示图)
        Graphics g = null;
        // 保存的图片  BitMap位图(.bmp), Image图片(.jpg,.jpeg,.png)
        Bitmap bmp = null;
        public Form1()
        {
            InitializeComponent();
            // 创建画板实例
            g = panel2.CreateGraphics();
            // 创建图片实例,设置宽高
            bmp = new Bitmap(panel2.Width, panel2.Height);
        }
        private void 文件FToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "图片(*.jpg)|*.JPG"; // 图片(*.jpg)|*.JPG|所有文件(*.*)|*.*
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                bmp = new Bitmap(dlg.FileName);
                g.DrawImage(bmp, new Point(0, 0));//重新绘制画板
            }
        }
        private void 保存SToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "图片(*.jpg)|*.JPG";
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    bmp.Save(saveFileDialog.FileName);
                }
                catch (Exception)
                {
                    MessageBox.Show("保存的文件名称,已经被独占打开!重新输入新文件名!");
                }
            }
        }
        private void 小号画笔ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TempData.PenWidth = 2;
        }
        private void 中号画笔ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TempData.PenWidth = 6;
        }
        private void 大号画笔ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TempData.PenWidth = 10;
        }
        private void 颜色ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ColorDialog colorDialog = new ColorDialog();
            if (colorDialog.ShowDialog() == DialogResult.OK)
            {
                TempData.PenColor = colorDialog.Color;
            }
        }
        private void 清空ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult dr = MessageBox.Show("你确定要清空吗?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (dr == DialogResult.Yes)
            {
                g.Clear(Color.White); // 清空画板1
                bmp = new Bitmap(panel2.Width, panel2.Height); // 重新创建bmp实例,清空图片内容
                g.DrawImage(bmp, new Point(0, 0)); //用清空后的图片重新绘制画板1
            }
        }
        private void panel2_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                paintStart = true;
                // MouseEventArgs类型的实例中,拥有坐标系统
                // EventArgs
                TempData.PrevPoint = new Point(e.X, e.Y);
            }
        }
        private void panel2_MouseMove(object sender, MouseEventArgs e)
        {
            // 用空白图片bmp当成画板的底板,重新生成一个画板2,画板2上画的图其实是画在bmp。
            // 为什么要创建两个画板:画板1为了画图并显示。画板2为了保存绘制的图片,橡皮擦。
            // 两个画板上的图保持一致。
            Graphics g2 = Graphics.FromImage(bmp);
            Pen pen = new Pen(TempData.PenColor, TempData.PenWidth);
            Point pt2 = new Point(e.X, e.Y);
            if (rbPen.Checked && paintStart)
            {
                g2.DrawLine(pen, TempData.PrevPoint, pt2);
                TempData.PrevPoint = pt2;
                g.DrawImage(bmp, 0, 0); // 把bmp上的图,重新再绘制到画板1上展示出来。
            }
            else if (rbEraser.Checked && paintStart)
            {
                g2.FillRectangle(new SolidBrush(panel2.BackColor), e.X, e.Y, TempData.PenWidth + 50, TempData.PenWidth + 50);
                g.DrawImage(bmp, 0, 0);  // 为了同步g和g2两个画板。
            }
        }
        private void panel2_MouseUp(object sender, MouseEventArgs e)
        {
            paintStart = false;
        }
    }
}
总结
这个程序实现了一个基本的绘图工具,允许用户加载图片、保存图片、选择画笔大小和颜色,并在 panel2 控件上进行绘图。它通过处理鼠标事件来实现绘图功能,并通过 Graphics 对象在 Bitmap 上绘制,然后将 Bitmap 显示在 panel2 上。


















