winfrom在图片上实现绘制

在控件加载入图片的基础上进行绘制内容

添加文字

首先就是要肯定输入的文字,还有文字的样式。ide

文字的样式用到了FontDialog控件,获取文字呢,就放个textbox就能够了。若是在输入文字的显示展现文字样式能够TextBox.Font = FontDialog.Font;字体

fontDialog1.ShowColor = true;  这样fontdialog控件就能够选择字体颜色了。this

 

if (this.fontDialog1.ShowDialog() == DialogResult.OK)
{spa

  这个 if 判断的是在用户选择字体样式并点击了肯定以后。
}3d

这里实现这个功能的原理,首先固然仍是须要一个image图片对象,能够用imagebitmap。而后以这个对象建立一个画布Graphics.FromImage(image);code

在初始化一个画笔对象new SolidBrush(this.fontDialog1.Color),这里将画笔的颜色设置为字体样式的颜色。对象

而后经过画布的 .DrawString()方法在画布的制定位置绘制指定的文本字符串。blog

画完以后要将绘制的文本显示在图像上,须要经过图片容器pictureBox1.Refresh()方法重绘控件。事件

由于这个画布是根据这个图片对象建立的,但并非再次建立一个图片,而是在这个图片对象上进行绘制。因此在控件刷新以后,就会显示绘制后的图片。图片

再就是须要肯定要将文本绘制到图片的那个位置

这里就须要肯定鼠标的坐标,鼠标点在那里就让文本显示在哪里。

这里使用了picturebox控件的鼠标抬起事件,就是在鼠标在控件上按下抬起以后就会触发。记录一个Point点。

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)//这里这个鼠标抬起事件里参数,e就是鼠标的对象,能够经过这个e获取坐标

  
if
(btn == "文字")//这个判断是由于我还有其余功能使用这个事件实现,因此经过这个String btn判断执行的什么操做 {   if (txt_tjwz.Text.Length > 0)//这里是判断文本框里有没有输入文本   {     Graphics gra = Graphics.FromImage(pic);//要进行处理的图片对象     //Graphics gra = pictureBox1.CreateGraphics();//这里这个画布也能够以控件做为对象绘制     SolidBrush brush = new SolidBrush(this.fontDialog1.Color);//初始化画笔 this.txt_tjwz.ForeColor     gra.DrawString(this.txt_tjwz.Text绘制的字符串, this.fontDialog1.Font字体样式, brush, e.X / Xsfbl按比例缩放后的坐标, e.Y / Ysfbl);//处理图片     this.pictureBox1.Refresh();//对显示图片的容器里面的控件刷新,以便及时显示添加的文字(控件中的图像为对象的时候)     bitlist.Add(new Bitmap(this.pictureBox1.Image));//将绘制完成的图片放入集合,供撤销用     txt_tjwz.Text = "";   } }

 

 添加线段

 和添加文字差很少,也是首先肯定线段的粗细,颜色,在肯定绘制线段的位置。由于是线段因此须要肯定两点Point

线段的粗细使用textbox让用户输入数字来获取,颜色经过ColorDialog控件,两点的位置经过两个事件来获取,初始点pt0经过鼠标的按下事件,结束点pt1经过抬起事件

可是还有一个问题,就是这样在肯定两点而后绘制成功以前,用户是看不见线段的,因此须要经过鼠标移动事件来实时显示线段的状态。

在用户点下鼠标获得pt0以后,当鼠标移入picturebox控件后就记录鼠标在控件中移动的坐标并绘制线段,由于是鼠标移动就会触发因此会持续绘制,此时就不须要用Refreah()刷新控件了。否则会把鼠标移动所产生的每一条线都记录下来。最后在鼠标中止肯定在一个点绘制后鼠标按键抬起,此时记录最后的坐标并绘制线段。而且根据初始与结束两点计算距离。

 

if (this.pictureBox1.Image.Width < 1)
                {
                    return;
                }
                if (!string.IsNullOrEmpty(btn))
                {
                    pt0 = new Point(e.X, e.Y);
                }
                else
                {
                    MessageBox.Show("请肯定操做");
                }
鼠标按下事件记录pt0
if (btn == "画线") 
                {
                    if (txt_tjsz.Text.Length > 0 && txt_tjsz.Text != "填入线段粗细数(1~9)")
                    {
                        pt1 = new Point(e.X, e.Y);
                        try
                        {
                            if (banjing(pt0, pt1) == 0)
                            {
                                return;
                            }
                            if (xian)
                            {
                                pictureBox1.Image = DrawLineInPicture1(pic, pt0, pt1, colorDialog1.Color, 2, DashStyle.Solid);//画线的方法
                            }
                            else
                            {
                                pictureBox1.Image = DrawLineInPicture1(pic, pt0, pt1, colorDialog1.Color, 2, DashStyle.Dash);//最后一个参数为线段的样式
                            }
                        }
                        catch (Exception ex)
                        {
                            pt0 = new Point(0);
                            MessageBox.Show("操做失败 " + ex.Message, "提示");
                        }
                    }
                   
                }
/// <summary>
        /// 在图片上绘制线段
        /// </summary>
        /// <param name="graphics">原始图片</param>
        /// <param name="p0">起始点</param>
        /// <param name="p1">终止点</param>
        /// <param name="LineColor">线的颜色</param>
        /// <param name="LineWidth">线的宽度</param>
        /// <param name="ds">线条样式</param>
        /// <returns></returns>
        public Bitmap DrawLineInPicture(Bitmap bmp, Point p0, Point p1, Color LineColor, int LineWidth, DashStyle ds)
        {//修改static
            if (bmp == null)
                return bmp;
            if (p0.X == p1.X || p0.Y == p1.Y)
                return bmp;
            Graphics g = Graphics.FromImage(bmp);
            Brush brush = new SolidBrush(LineColor);
            Pen pen = new Pen(brush, LineWidth);
            //pen.Alignment = PenAlignment.Inset; 
            pen.DashStyle = ds;
            if(btn!="画角")
            {
                System.Drawing.Drawing2D.AdjustableArrowCap lineArrow =
    new System.Drawing.Drawing2D.AdjustableArrowCap(Convert.ToInt32(txt_tjsz.Text)/2, Convert.ToInt32(txt_tjsz.Text)/2, true);//设置箭头大小
                pen.CustomEndCap = lineArrow;
            }
            //g.DrawLine(pen,p0,p1);
            g.DrawLine(pen, p0.X / Xsfbl,p0.Y/Ysfbl,p1.X/Xsfbl,p1.Y/Ysfbl);
            g.Dispose();
            return bmp; 
        }
在图片上绘制线段
鼠标MouseUp事件
if
(btn == "画线") { if (txt_tjsz.Text.Length > 0 && txt_tjsz.Text != "填入线段粗细数(1~9)") { if (banjing(pt0, pt1) == 0) { return; } if (xian) { pictureBox1.Image = DrawLineInPicture(pic, pt0, pt1, colorDialog1.Color, Convert.ToInt32(txt_tjsz.Text), DashStyle.Solid); } else { pictureBox1.Image = DrawLineInPicture(pic, pt0, pt1, colorDialog1.Color, Convert.ToInt32(txt_tjsz.Text), DashStyle.Dash); } this.pictureBox1.Refresh(); Point cp = new Point((pt1.X - pt0.X) / 2, (pt1.Y - pt0.Y) / 2); Point np = new Point(cp.X + pt0.X, cp.Y + pt0.Y);//算出线段的中心点               //计算出说话线段的长度 Graphics gra = Graphics.FromImage(this.pictureBox1.Image);//要进行处理的对象 SolidBrush brush = new SolidBrush(colorDialog1.Color);//初始化画笔 gra.DrawString(banjing(pt0, pt1).ToString(), this.fontDialog2.Font, brush, np.X / Xsfbl, np.Y / Ysfbl);//处理图片 this.pictureBox1.Refresh();//对显示图片的容器里面的控件刷新,以便及时显示添加的文字(控件中的图像为对象的时候) bitlist.Add(new Bitmap(this.pictureBox1.Image)); pt0 = new Point(0); } }

 

 

 绘制角度

 绘制角度我用的 方法就是绘制两条线段。

先绘制一条,再根据角度旋转pt1点,而后链接pt0和新获得的pt2

嗯,也能够选择线段的颜色,粗细默认是2,根据以前计算获得的图片缩放比例改变。

也是先肯定pt0,而后鼠标移动事件中不停绘制线段显示,知道鼠标抬起记录pt1pt2,而后刷新控件。

if (btn == "画角")
                {
                    if (txt_tjsz.Text.Length > 0&& txt_tjsz.Text != "填入角度度数")
                    {
                        pt1 = new Point(e.X, e.Y);
                        pictureBox1.Image = DrawLineInPicture1(pic, pt0, pt1, colorDialog1.Color, 2, DashStyle.Solid);


                        Point pt2 = GetNewPoint(Convert.ToInt32(txt_tjsz.Text), pt0, pt1);
                        pictureBox1.Image = DrawLineInPicture1(pic, pt0, pt2, colorDialog1.Color, 2, DashStyle.Solid);
                    }
                    else
                    {
                        pt0 = new Point(0);
                        MessageBox.Show("请填写角度", "提示");
                    }

                }
鼠标MouseMove
if (btn == "画角")
                {
                    if (txt_tjsz.Text.Length > 0 && txt_tjsz.Text != "填入角度度数")
                    {
                        pt1 = new Point(e.X, e.Y);
                        pictureBox1.Image = DrawLineInPicture(pic, pt0, pt1, colorDialog1.Color, Convert.ToInt32(2/Xsfbl), DashStyle.Solid);
                        //pictureBox1.Refresh();//刷新控件绘制角的第一条线
                        //bitlist.Add(new Bitmap(this.pictureBox1.Image));

                        Point pt2 = GetNewPoint(Convert.ToInt32(txt_tjsz.Text), pt0, pt1);//顺时针
                        pictureBox1.Image = DrawLineInPicture(pic, pt0, pt2, colorDialog1.Color, Convert.ToInt32(2 / Xsfbl), DashStyle.Solid);
                        pictureBox1.Refresh();//刷新控件绘制角的第二条线
                        bitlist.Add(new Bitmap(this.pictureBox1.Image));
                        pt0 = new Point(0);
                    }
                    else
                    {
                        pt0 = new Point(0);
                        MessageBox.Show("请填写角度", "提示");
                    }
MouseUp

 

/// <summary>

/// 获取移动角度的新坐标

/// </summary>

/// <param name="Rate">旋转角度</param>

/// <param name="CirPoint">圆心坐标</param>

/// <param name="MovePoint">移动的坐标</param>

/// <returns></returns>

private Point GetNewPoint(double Rate, Point CirPoint, Point MovePoint)

{

double Rage2 = Rate / 180 * Math.PI;

//B点绕A点转R度获得C点坐标,flag: 顺时针1,反时针-1:B是转的点,A是圆心

//C.X=(B.X-A.X)*COS(R*flag)-(B.Y-A.Y)*Sin(R*flag);

//C.Y= (B.Y-A.Y)*COS(R*flag)+(B.X-A.X)*sin(R*flag);

//转的点坐标-圆心坐标

//圆心坐标+计算坐标=新位置的坐标

int newx = (int)((MovePoint.X - CirPoint.X) * Math.Cos(Rage2) - (MovePoint.Y - CirPoint.Y) * Math.Sin(Rage2));

int newy = (int)((MovePoint.Y - CirPoint.Y) * Math.Cos(Rage2) + (MovePoint.X - CirPoint.X) * Math.Sin(Rage2));

Point newpoint=new Point(CirPoint.X + newx, CirPoint.Y + newy);

//计算长度

double lineJ = Math.Sqrt(Math.Pow(Math.Max(newpoint.X, CirPoint.X) - Math.Min(newpoint.X, CirPoint.X), 2) + Math.Pow(Math.Max(newpoint.Y, CirPoint.Y) - Math.Min(newpoint.Y, CirPoint.Y), 2));

return newpoint;

}
获取移动角度的新坐标
相关文章
相关标签/搜索