[自用存档]c#自制窗体绘画程序0.2.1代码

C#自制窗体绘画程序0.2.1代码

仅供自用
效果展示
自制窗体绘画程序
有一个bug待解决:切换橡皮时会自动更改画笔粗细

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace DrawForms02
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            pB_penColor.BackColor = pen1.Color; //画笔颜色显示框初始化
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)   //快捷键
        {
            if(e.KeyCode == Keys.C)
            {
                CleanPicture(bm_main, g_main, pB_main); //清理屏幕
            }
            if(e.KeyCode == Keys.G)
            {
                this.Cursor = Cursors.Cross; // 将鼠标指针设置为十字光标,表示取色状态
                this.mouseState = MouseState.colorPicker;   // 切换笔的状态
            }
            if(e.KeyCode == Keys.S)
            {
                DialogResult dialogResult = colorDialog1.ShowDialog();
                if (dialogResult == DialogResult.OK)
                {
                    selectColor = colorDialog1.Color;
                    pen1.Color = selectColor;
                    pB_penColor.BackColor = selectColor;
                }
            }
            if(e.KeyCode == Keys.E) //橡皮
            {
                pen1.Color = Color.White;
                pB_penColor.BackColor = Color.White;
                pen1.Width = 20;
                trackBar_penSize.Value = 20;
                textBox_penSize.Text = "20";
            }
        }

        enum MouseState //区分好是 画笔状态 还是 取色器状态
        {
            pen,    //画笔
            colorPicker //取色器
        }
        MouseState mouseState = MouseState.pen;

        Bitmap bm_main;  //画图bitmap
        Graphics g_main;
        Point p1, p2;   //线段的两个点
        Pen pen1 = new Pen(Color.Red, 1);   //画笔
        bool is_pen_down = false;   //判断画笔是否落下
        bool is_first_point = true; //记录第一个点 即落笔位置


        private void pB_main_Resize(object sender, EventArgs e) //初始化事件
        {
            bm_main = new Bitmap(pB_main.Width, pB_main.Height);
            g_main = Graphics.FromImage(bm_main);
            g_main.Clear(Color.White);
        }

        private void pB_main_MouseDown(object sender, MouseEventArgs e)
        {
            is_pen_down = true;
            is_first_point = true;

            /*旧版v0.1取色功能
            if (mouseState == MouseState.colorPicker)
            {
                Point p = this.PointToScreen(e.Location);
                Color pickedColor = GetPixelColor(p);
                pen1.Color = pickedColor;                      // 将颜色值用于你想要的操作,例如显示在标签上或者将其应用到其他控件上
                pB_penColor.BackColor = pickedColor;
                this.Cursor = Cursors.Default;  // 恢复鼠标指针为默认状态
                this.mouseState = MouseState.pen;   //笔的状态恢复
                //this.MouseDown -= Form1_MouseDown;  // 移除鼠标按下事件处理程序
                //this.MouseDown -= pB_main_MouseDown;
                //this.MouseDown -= pB_color_MouseDown;
            }
            */
            if (mouseState == MouseState.colorPicker)   //直接取色(原图无放缩)
            {
                Point p = new Point(e.X, e.Y);
                Color pickedColor = this.bm_main.GetPixel(p.X, p.Y);
                pen1.Color = pickedColor;                      // 将颜色值用于你想要的操作,例如显示在标签上或者将其应用到其他控件上
                pB_penColor.BackColor = pickedColor;
                this.Cursor = Cursors.Default;  // 恢复鼠标指针为默认状态
                this.mouseState = MouseState.pen;   //笔的状态恢复
            }
        }

        private void pB_main_MouseUp(object sender, MouseEventArgs e)
        {
            is_pen_down = false;
        }

        private void pB_main_MouseMove(object sender, MouseEventArgs e) //重点
        {
            if(mouseState == MouseState.pen)    //画笔状态
            {
                if (is_first_point)  //确定落笔时第一点位置
                {
                    p1 = new Point(e.X, e.Y);
                    is_first_point = false;
                }

                if (is_pen_down)
                {
                    p2 = new Point(e.X, e.Y);
                    //pen1.Color = Color.Blue;
                    //pen1.Width = 1;
                    g_main.DrawLine(pen1, p1, p2);   //画线
                    p1 = p2;

                    pB_main.Image = bm_main;    //在控件上显示bitmap的内容
                }
            }

            if (mouseState == MouseState.colorPicker)    //取色时,即时显示颜色
            {
                Point p = new Point(e.X, e.Y);
                pB_penColor.BackColor = this.bm_main.GetPixel(p.X, p.Y);
            }
        }

        private void b_clean_Click(object sender, EventArgs e)  //清理屏幕按钮
        {
            //g_main.Clear(Color.White);
            //pB_main.Image = bm_main;    //在控件上显示bitmap的内容
            CleanPicture(bm_main, g_main, pB_main);
        }

        private void CleanPicture(Bitmap b, Graphics g, PictureBox p)   //清理函数
        {
            g.Clear(Color.White);
            p.Image = b;
        }

        //Bitmap bm_colorWheel = new Bitmap(16, 16);   //色盘bitmap
        Bitmap bm_colorWheel;
        Graphics g_bm_color;
        //Graphics g_pB_color; 新版imageV2显示要用的变量
        Bitmap bm_colorPictureBoxView; //新版imageV3显示要用的变量
        Point p_pB_c;   //鼠标落点
        bool is_pen_down_pB_c = false;  //判断画笔是否落下
        bool is_colorPixel_draw = false;    //判断是否已经画完一个矩形
        //bool is_first_point_pB_c = true;    //记录第一个点 即落笔位置
        Color selectColor;
        //Brush brush_colorWheel = new SolidBrush(Color.Black); //新版imageV2显示要用的变量

        private void b_colorSelect_Click(object sender, EventArgs e)    //选择颜色按钮
        {
            DialogResult dialogResult = colorDialog1.ShowDialog();
            if(dialogResult == DialogResult.OK)
            {
                selectColor = colorDialog1.Color;
                pen1.Color = selectColor;
                pB_penColor.BackColor = selectColor;
            }
        }

        private void b_colorSelect2_Click(object sender, EventArgs e) //控制台选择颜色按钮
        {
            DialogResult dialogResult = colorDialog1.ShowDialog();
            if (dialogResult == DialogResult.OK)
            {
                selectColor = colorDialog1.Color;
                pen1.Color = selectColor;
                pB_penColor.BackColor = selectColor;
            }
        }

        private void pB_color_Resize(object sender, EventArgs e)    //初始化
        {
            //初始化为pictureBox大小
            //bm_colorWheel = new Bitmap(pB_color.Width, pB_color.Height);
            bm_colorWheel = new Bitmap(8, 8);
            g_bm_color = Graphics.FromImage(bm_colorWheel); //bitmap上的画布初始化
            g_bm_color.Clear(Color.White);

            //新版imageV2显示要用的变量
            //g_pB_color = pB_color.CreateGraphics(); //pictureBox控件上的画布初始化
            //label2_debug.Text = g_pB_color.DpiX + ", " + g_pB_color.DpiY; //debug

            //新版imageV3显示要用的变量
            bm_colorPictureBoxView = new Bitmap(pB_color.Width, pB_color.Height);
        }

        private void pB_color_MouseDown(object sender, MouseEventArgs e)
        {
            if(mouseState == MouseState.pen)
            {
                is_pen_down_pB_c = true;

                if (is_pen_down_pB_c == true && is_colorPixel_draw == false)
                {
                    //矩形绘制(已弃用)
                    //g_color.FillRectangle
                    //    (new SolidBrush(pen1.Color), p_pB_c.X, p_pB_c.Y, 1, 1);

                    //p_pB_c = new Point(e.X, e.Y);
                    p_pB_c = new Point(e.X * bm_colorWheel.Width / pB_color.Width, e.Y * bm_colorWheel.Height / pB_color.Height);

                    //图片缩放则画图方式也要缩放
                    //g_color.DrawRectangle
                    //    (pen1, p_pB_c.X * (bm_colorWheel.Width / pB_color.Width),
                    //     p_pB_c.Y * (bm_colorWheel.Height / pB_color.Height), 2, 2);

                    //pB_color.Image = bm_colorWheel; //新版更新imageV3

                    //g_bm_color.DrawRectangle(pen1, p_pB_c.X, p_pB_c.Y, 1, 1); //先在bitmap上绘制 更新imageV0
                    bm_colorWheel.SetPixel(p_pB_c.X, p_pB_c.Y, pen1.Color); //新版更新imageV4
                    //pB_color.Image = bm_colorWheel; //更新imageV0

                    

                    //DrawImage(bm_colorWheel, pB_color.CreateGraphics(), pB_color); //新版更新imageV1
                    //DrawImageV2(bm_colorWheel, g_pB_color, pB_color, brush_colorWheel); //新版更新imageV2
                    DrawImageV3(bm_colorWheel, bm_colorPictureBoxView); //新版更新imageV3
                    pB_color.Image = bm_colorPictureBoxView; //新版更新imageV3
                    is_colorPixel_draw = true;
                    //label2_debug.Text = e.X + ", " + e.Y; //debug
                }
            }

            /* 原取色功能v0.1废弃
            if (mouseState == MouseState.colorPicker)
            {
                Point p = this.PointToScreen(e.Location);
                Color pickedColor = GetPixelColor(p);
                pen1.Color = pickedColor;                      // 将颜色值用于你想要的操作,例如显示在标签上或者将其应用到其他控件上
                pB_penColor.BackColor = pickedColor;
                this.Cursor = Cursors.Default;  // 恢复鼠标指针为默认状态
                this.mouseState = MouseState.pen;   //笔的状态恢复
                //this.MouseDown -= Form1_MouseDown;  // 移除鼠标按下事件处理程序
                //this.MouseDown -= pB_main_MouseDown;
                //this.MouseDown -= pB_color_MouseDown;
            }
            */

            if (mouseState == MouseState.colorPicker)
            {
                Point p = new Point(e.X * bm_colorWheel.Width / pB_color.Width, e.Y * bm_colorWheel.Height / pB_color.Height);
                Color pickedColor = this.bm_colorWheel.GetPixel(p.X, p.Y);
                pen1.Color = pickedColor;                      // 将颜色值用于你想要的操作,例如显示在标签上或者将其应用到其他控件上
                pB_penColor.BackColor = pickedColor;
                this.Cursor = Cursors.Default;  // 恢复鼠标指针为默认状态
                this.mouseState = MouseState.pen;   //笔的状态恢复
            }
        }

        private void pB_color_MouseUp(object sender, MouseEventArgs e)
        {
            is_pen_down_pB_c = false;
            is_colorPixel_draw = false;
        }
        
        private void pB_color_MouseMove(object sender, MouseEventArgs e)
        {
            /*
            if(is_pen_down_pB_c == true && is_colorPixel_draw == false)
            {
                //矩形绘制(已弃用)
                //g_color.FillRectangle
                //    (new SolidBrush(pen1.Color), p_pB_c.X, p_pB_c.Y, 1, 1);

                //p_pB_c = new Point(e.X, e.Y);
                p_pB_c = new Point(e.X * bm_colorWheel.Width / pB_color.Width, e.Y * bm_colorWheel.Height / pB_color.Height);

                //图片缩放则画图方式也要缩放
                //g_color.DrawRectangle
                //    (pen1, p_pB_c.X * (bm_colorWheel.Width / pB_color.Width),
                //     p_pB_c.Y * (bm_colorWheel.Height / pB_color.Height), 2, 2);

                g_color.DrawRectangle(pen1, p_pB_c.X, p_pB_c.Y , 1, 1);
                //pB_color.Image = bm_colorWheel; //更新imageV0
                //DrawImage(bm_colorWheel, pB_color.CreateGraphics(), pB_color); //新版更新imageV1
                DrawImageV2(bm_colorWheel, pB_color.CreateGraphics(), pB_color, brush_colorWheel); //新版更新imageV2
                is_colorPixel_draw = true;
                
            }
            */

            if(mouseState == MouseState.colorPicker)    //取色时,即时显示颜色
            {
                //Point p = this.PointToScreen(e.Location); 
                Point p = new Point(e.X * bm_colorWheel.Width / pB_color.Width, e.Y * bm_colorWheel.Height / pB_color.Height);
                //pB_penColor.BackColor = GetPixelColor(p); //已废弃
                pB_penColor.BackColor = this.bm_colorWheel.GetPixel(p.X, p.Y);
            }
        }

        //取色功能
        //事件功能的+-是怎么工作的?

        private void b_colorPick_Click(object sender, EventArgs e)  //取色按钮
        {
            this.Cursor = Cursors.Cross; // 将鼠标指针设置为十字光标,表示取色状态
            this.mouseState = MouseState.colorPicker;   // 切换笔的状态
            //this.MouseDown += Form1_MouseDown; // 添加鼠标按下事件处理程序
            //this.MouseDown += pB_main_MouseDown;
            //this.MouseDown += pB_color_MouseDown;
        }

        //文件保存
        private void save_ToolStripMenuItem_Click(object sender, EventArgs e)   //点击上方菜单 文件->保存
        {
            //saveFileDialog1.ShowDialog(); //第一次弹出保存对话框
            //saveFileDialog1.
            //this.saveFileDialog1.Filter = "Jpg 图片|*.jpg|Bmp 图片|*.bmp|Gif 图片|*.gif|Png 图片|*.png|Wmf  图片|*.wmf";
            //this.saveFileDialog1.FileName = "test";
            //this.saveFileDialog1.AddExtension = true;
            //this.saveFileDialog1.DefaultExt = "jpg";    //默认保存文件格式

            if(saveFileDialog1.ShowDialog() == DialogResult.OK) //点击保存  //第二次弹出保存对话框
            {
                //bm_main.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                bm_main.Save(saveFileDialog1.FileName);
            }
        }   //连续保存两次?

        
        private void DrawImage(Bitmap bitmap, Graphics pictureBoxGraphics, PictureBox pictureBox) //绘制图像
        {
            pictureBoxGraphics.DrawImage(bitmap, 0, 0, pictureBox.Width, pictureBox.Height);
        }

        private void DrawImageV2(Bitmap bitmap, Graphics pictureBoxGraphics, PictureBox pictureBox, Brush brush)
        //待改进功能:当 pictureBox.Width / bitmap.Width 不能整除时,如何处理偏移
        {
            Point drawingPonit = new Point();
            Color drawingColor = new Color();
            for(int bitmapY = 0; bitmapY < bitmap.Height; bitmapY++) {
                for(int bitmapX = 0; bitmapX < bitmap.Width; bitmapX++) {
                    //drawingPonit.X = bitmapX * (pictureBox.Width / bitmap.Width); //确定绘画开始位置
                    //drawingPonit.Y = bitmapY * (pictureBox.Height / bitmap.Height);
                    drawingPonit.X = (int)((double)bitmapX * (double)(pictureBox.Width / bitmap.Width)); //确定绘画开始位置
                    drawingPonit.Y = (int)((double)bitmapY * (double)(pictureBox.Height / bitmap.Height));
                    drawingColor = bitmap.GetPixel(bitmapX, bitmapY); //确定绘画颜色
                    brush = new SolidBrush(drawingColor);
                    pictureBoxGraphics.FillRectangle
                        (
                         brush,
                         drawingPonit.X,
                         drawingPonit.Y,
                         //(int)Math.Round((double)(pictureBox.Width / bitmap.Width)),
                         //(int)Math.Round((double)(pictureBox.Height / bitmap.Height))
                         (int)((bitmapX + 1) * (double)(pictureBox.Width / bitmap.Width)) - drawingPonit.X,
                         (int)((bitmapY + 1) * (double)(pictureBox.Height / bitmap.Height)) - drawingPonit.Y
                        );
                }
            }
        }

        private void DrawImageV3(Bitmap bm_input, Bitmap bm_output)
        {
            Point point_input = new Point();
            Color color_input;
            for (int bm_output_Y = 0; bm_output_Y < bm_output.Height; bm_output_Y++)
                for (int bm_output_X = 0; bm_output_X < bm_output.Width; bm_output_X++)
                {
                    //求bm_output像素点对应的bm_input像素点  注意如何避免除法舍弃小数
                    point_input.X = (int)(((float)bm_output_X / bm_output.Width) * bm_input.Width);
                    point_input.Y = (int)(((float)bm_output_Y / bm_output.Height) * bm_input.Height);
                    color_input = bm_input.GetPixel(point_input.X, point_input.Y);
                    //绘制
                    bm_output.SetPixel(bm_output_X, bm_output_Y, color_input);
                }
        }

        

        //画笔粗细更改功能
        //拖动条更改画笔粗细
        private void trackBar_penSize_ValueChanged(object sender, EventArgs e)
        {
            pen1.Width = trackBar_penSize.Value; //更改pen1粗细
            textBox_penSize.Text = trackBar_penSize.Value.ToString(); //更改textBox显示值
        }

        //textBox输入功能
        private void textBox_penSize_KeyPress(object sender, KeyPressEventArgs e) //按键事件
        {
            if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar)) // 判断按键不是控制键且不是数字
            {
                e.Handled = true; // 取消该按键的处理
            }
        }

        private void textBox_penSize_KeyDown(object sender, KeyEventArgs e) //检测回车并响应更新
        {
            if(e.KeyCode == Keys.Enter) //Enter键按下
            {
                if (textBox_penSize.Text.Length > 0) //字符串有内容时
                {
                    int penSize = int.Parse(textBox_penSize.Text); //int.Parse 函数功能:str转int
                    if (penSize < 1)
                    {
                        penSize = 1;
                        textBox_penSize.Text = "1";
                    }
                    else if (penSize > 20)
                    {
                        penSize = 20;
                        textBox_penSize.Text = "20";
                    }
                    pen1.Width = penSize; //设置笔
                    trackBar_penSize.Value = penSize; //设置滑条
                    //textBox_penSize.Text = ToString();
                    this.ActiveControl = null; //取消焦点(?)
                }
            }
        }

        //橡皮按钮
        private void b_eraser_Click(object sender, EventArgs e)
        {
            pen1.Color = Color.White;
            pB_penColor.BackColor = Color.White;
            pen1.Width = 20;
            trackBar_penSize.Value = 20;
            textBox_penSize.Text = "20";
        }


        /*
        private void textBox_penSize_TextChanged(object sender, EventArgs e) //文本更新事件
        {
            //int penSize;
            //bool success = int.TryParse(textBox_penSize.Text, out penSize);

            if (textBox_penSize.Text.Length > 0) //字符串有内容时
            {
                int penSize = int.Parse(textBox_penSize.Text); //int.Parse 函数功能:str转int
                if (penSize < 1)
                {
                    penSize = 1;
                }
                else if (penSize > 10)
                {
                    penSize = 10;
                }
                pen1.Width = penSize;
                trackBar_penSize.Value = penSize;
            }

        }
        */
    }
}

/* 参考代码 第一版保存
        private void button2_Click(object sender, EventArgs e)  //保存文件按钮
        {
            savePath = textBox1.Text;
            if (Directory.Exists(savePath))
            {
                bitmap.Save(savePath + "\\test.jpg");
                textBox1.Text = (savePath + " 保存成功!文件名为test.jpg");
            }
            else 
            {
                textBox1.Text = wrongPathMessage;
            }
        }
        */

/*
private void Form1_MouseDown(object sender, MouseEventArgs e)   //form窗体取色
{
    /*
    if(mouseState == MouseState.colorPicker)
    {
        //Color pickedColor = GetPixelColor(e.Location); // 获取鼠标点击位置的颜色
        Point p = this.PointToScreen(e.Location);
        Color pickedColor = GetPixelColor(p);
        pen1.Color = pickedColor;                      // 将颜色值用于你想要的操作,例如显示在标签上或者将其应用到其他控件上
        pB_penColor.BackColor = pickedColor;
        this.Cursor = Cursors.Default;  // 恢复鼠标指针为默认状态
        this.mouseState = MouseState.pen;   //笔的状态恢复
        //this.MouseDown -= Form1_MouseDown;  // 移除鼠标按下事件处理程序
        //this.MouseDown -= pB_main_MouseDown;
        //this.MouseDown -= pB_color_MouseDown;
    }

}
*/

/*
private Color GetPixelColor(Point location) //取色函数  //已弃用
{
    using (Bitmap bmp = new Bitmap(1, 1))
    {
        using (Graphics g = Graphics.FromImage(bmp))
        {
            g.CopyFromScreen(location, new Point(0, 0), new Size(1, 1));    //取色不稳定
        }
        return bmp.GetPixel(0, 0);
    }
}
*/

//取色功能
//事件功能的+-是怎么工作的?
/*
private void b_colorPick_Click(object sender, EventArgs e)  //取色按钮
{
    this.Cursor = Cursors.Cross; // 将鼠标指针设置为十字光标,表示取色状态
    this.MouseDown += Form1_MouseDown; // 添加鼠标按下事件处理程序
}

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
    //Color pickedColor = GetPixelColor(e.Location); // 获取鼠标点击位置的颜色
    Point p = this.PointToScreen(e.Location);
    Color pickedColor = GetPixelColor(p);
    pen1.Color = pickedColor;                      // 将颜色值用于你想要的操作,例如显示在标签上或者将其应用到其他控件上
    pB_penColor.BackColor = pickedColor;
    this.Cursor = Cursors.Default;  // 恢复鼠标指针为默认状态
    this.MouseDown -= Form1_MouseDown;  // 移除鼠标按下事件处理程序
}

private Color GetPixelColor(Point location) //取色函数
{
    using (Bitmap bmp = new Bitmap(1, 1))
    {
        using (Graphics g = Graphics.FromImage(bmp))
        {
            g.CopyFromScreen(location, new Point(0, 0), new Size(1, 1));
        }
        return bmp.GetPixel(0, 0);
    }
}
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值