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

添加文字

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

文字的样式用到了FontDialog控件,获取文字呢,就放个textbox就可以了。如果在输入文字的显示展示文字样式可以TextBox.Font = FontDialog.Font;

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

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

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

这里实现这个功能的原理,首先当然还是需要一个image图片对象,可以用imagebitmap。然后以这个对象创建一个画布Graphics.FromImage(image);

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

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

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

因为这个画布是根据这个图片对象创建的,但并不是再次创建一个图片,而是在这个图片对象上进行绘制。所以在控件刷新之后,就会显示绘制后的图片。

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

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

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

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

  
if (btn == "文字")//这个判断是因为我还有其他功能使用这个事件实现,所以通过这个String btn判断执行的什么操作
{
  if (txt_tjwz.Text.Length > )//这里是判断文本框里有没有输入文本
  {
    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 < )
{
return;
}
if (!string.IsNullOrEmpty(btn))
{
pt0 = new Point(e.X, e.Y);
}
else
{
MessageBox.Show("请确定操作");
}

鼠标按下事件记录pt0

if (btn == "画线")
{
if (txt_tjsz.Text.Length > && txt_tjsz.Text != "填入线段粗细数(1~9)")
{
pt1 = new Point(e.X, e.Y);
try
{
if (banjing(pt0, pt1) == )
{
return;
}
if (xian)
{
pictureBox1.Image = DrawLineInPicture1(pic, pt0, pt1, colorDialog1.Color, , DashStyle.Solid);//画线的方法
}
else
{
pictureBox1.Image = DrawLineInPicture1(pic, pt0, pt1, colorDialog1.Color, , DashStyle.Dash);//最后一个参数为线段的样式
}
}
catch (Exception ex)
{
pt0 = new Point();
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)/, Convert.ToInt32(txt_tjsz.Text)/, 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 > && txt_tjsz.Text != "填入线段粗细数(1~9)")
{
if (banjing(pt0, pt1) == )
{
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) / , (pt1.Y - pt0.Y) / );
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();
}
}

绘制角度

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

先绘制一条,再根据角度旋转pt1点,然后连接pt0和新得到的pt2

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

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

if (btn == "画角")
{
if (txt_tjsz.Text.Length > && txt_tjsz.Text != "填入角度度数")
{
pt1 = new Point(e.X, e.Y);
pictureBox1.Image = DrawLineInPicture1(pic, pt0, pt1, colorDialog1.Color, , DashStyle.Solid); Point pt2 = GetNewPoint(Convert.ToInt32(txt_tjsz.Text), pt0, pt1);
pictureBox1.Image = DrawLineInPicture1(pic, pt0, pt2, colorDialog1.Color, , DashStyle.Solid);
}
else
{
pt0 = new Point();
MessageBox.Show("请填写角度", "提示");
} }

鼠标MouseMove

if (btn == "画角")
{
if (txt_tjsz.Text.Length > && txt_tjsz.Text != "填入角度度数")
{
pt1 = new Point(e.X, e.Y);
pictureBox1.Image = DrawLineInPicture(pic, pt0, pt1, colorDialog1.Color, Convert.ToInt32(/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( / Xsfbl), DashStyle.Solid);
pictureBox1.Refresh();//刷新控件绘制角的第二条线
bitlist.Add(new Bitmap(this.pictureBox1.Image));
pt0 = new Point();
}
else
{
pt0 = new Point();
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 /  * 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), ) + Math.Pow(Math.Max(newpoint.Y, CirPoint.Y) - Math.Min(newpoint.Y, CirPoint.Y), ));

return newpoint;

}

获取移动角度的新坐标

winfrom在图片上实现绘制的更多相关文章

  1. android 加载自定义图片并在图片上绘图

    来源:毕设 关键词:Bitmap Canvas //毕设中需要自定义室内地图,并且在地图上绘制轨迹 //此处是一个测试Demo,实现图片的加载和记录手指在屏幕上的运动轨迹 图片的载入 使用系统提供的内 ...

  2. 使用ImageMagick 在图片上绘制粗斜体的中文也许是一个错误。

    测试发现: ImageMagick使用中文字体,在图片上绘制带粗或斜体的中文,看不到效果. 如果使用英文字体,绘制粗或斜体的英文,99%都有效果. 今天无意看到一篇文章提到: convert -lis ...

  3. Android 使用Canvas在图片上绘制文字

    一个小应用,在图片上绘制文字,以下是绘制文字的方法,并且能够实现自动换行,字体自动适配屏幕大小 private void drawNewBitmap(ImageView imageView, Stri ...

  4. 图片上传代码(C#)

    //上传 protected void Button1_Click(object sender, EventArgs e)        {            if (FileUpload1.Ha ...

  5. ASP.NET 图片上传工具类 upload image简单好用功能齐全

    使用方法: UploadImage ui = new UploadImage(); /***可选参数***/ ui.SetWordWater = "哈哈";//文字水印 // ui ...

  6. [上传下载] C# ImageUpload图片上传类教程与源码下载 (转载)

    点击下载 ImageUpload.zip 功能如下图片1.设置属性后上传图片,用法如下 /// <summary> /// 图片上传类 /// </summary> //--- ...

  7. Android仿微信图片上传,可以选择多张图片,缩放预览,拍照上传等

    仿照微信,朋友圈分享图片功能 .可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 .很不错的源码,大家有需要可以下载看看 . 微信 微信 微信 ...

  8. 安卓自定义View实现图片上传进度显示(仿QQ)

    首先看下我们想要实现的效果如下图(qq聊天中发送图片时的效果): 再看下图我们实现的效果: 实现原理很简单,首先我们上传图片时需要一个进度值progress,这个不管是自己写的上传的方法还是使用第三方 ...

  9. html图片上传阅览并且点击放大

                  关闭   qq_31540195的博客       目录视图 摘要视图 订阅 异步赠书:9月重磅新书升级,本本经典           程序员9月书讯      每周荐书: ...

随机推荐

  1. #define用法

    1.简单的define定义 #define MAXTIME 1000 一个简单的MAXTIME就定义好了,它代表1000,如果在程序里面写 if(i<MAXTIME) { // } 编译器在处理 ...

  2. sqlzoo练习题答案

    title: SQL-Learning date: 2019-03-12 20:37:21 tags: SQL --- 这是关于在一个SQL学习网站的练习题答案记录:SQL教程 SQL基础 由一些简单 ...

  3. 扩充 jQuery EasyUI Datagrid 数据行鼠标悬停/离开事件(onMouseOver/onMouseOut)

    客户需求: jQuery EasyUI Datagrid 用户列表鼠标悬停/离开数据行时显示人员头像(onMouseOver/onMouseOut) 如图所示,Datagrid 鼠标悬停/离开数据行时 ...

  4. NAT功能测试

    一.测试目标和功能: 1.内网设备可以访问外网的IP: 2.外网PC可以登录内网设备的telnet. 二.设备硬件结构 1.3135相当于交换机: 2.eth0.netra和业务网口通过内部端口连接3 ...

  5. Django-MTV模型

    MTV模型 Django的MTV分别代表: Model(模型):负责业务对象与数据库的对象(ORM) Template(模版):负责如何把页面展示给用户 View(视图):负责业务逻辑,并在适当的时候 ...

  6. android流畅度比Ios差的原因

    Andorid更新了一个版本又一个版本,硬件从单核到双核到四核,系统流畅度总算基本能和iOS持平了.不过人们不禁会问,为什么都是基于Linux,两个系统会差别如此大?为什么iPhone 4用单核处理器 ...

  7. 如何实现session共享

    http://www.cnblogs.com/xiehuiqi220/p/3592300.html 首先我们应该明白,为什么要实现共享,如果你的网站是存放在一个机器上,那么是不存在这个问题的,因为会话 ...

  8. mysql压缩表空间

    REPAIR TABLE `table_name` 修复表 OPTIMIZE TABLE `table_name` 优化表 OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] ...

  9. JavaScript中的跨域详解(一)

    同源策略 所谓的同源策略,指的是浏览器对不同源的脚本或者文本访问方式进行的限制. 所谓同源,就是指两个页面具有相同的协议,主机(也常说域名),端口,三个要素缺一不可. 同源政策的目的,是为了保证用户信 ...

  10. cocos2dx中快速完成一段可播放动画

    版本:cocos2dx 2.2.6 IDE: VS2012 语言:C++98 CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteF ...