c# GDI+简单绘图(四)

UG/NX 二次开发(C#)自动出2D零件图(标准件配置Bata版) 这个版本已初具自动出2D图的雏形,能满足标准件经过配置后出图的基本需求,后面会继续挖掘并分享给大家,如果对源码感兴趣可以给我留言索要。同时也欢迎各位大佬提供宝贵意见和建议。 虽然没能实现自动出2D零件图,但是拿着去跟老板交差,应该勉强过关吧,毕竟也年底了,大家都想早点回家过年。 阅读详情

前几篇我已经向大家介绍了如何使用GDI+来绘图,并做了一个截图的实例,这篇我向大家介绍下如何来做一个类似windows画图的工具.
  个人认为如果想做一个功能强大的绘图工具,那么单纯掌握GDI还远远不够,我的目前也只能做一个比较简单的绘图工具了.不足之处,欢迎大家讨论!


  先来看一下最终效果吧:

  
  主要实现功能:画直线,矩形,橡皮,圆形,切换颜色,打开图片,保存图片,清除图片,手动调节画布大小;软件刚启动时,为一张空白画布,我们可以直接在画布上绘画,也可以通过菜单中的“打开”,导入一张图片,然后我们就可以在这张图片上进行绘制。
  平台:VS2005 WINFORM

  由于代码过多,在这里只简要介绍下制作步骤,提供大家工程下载.
  1.对整个界面进行布局.
  2.实现绘图工具的功能
  3.实现颜色拾取的功能,这里我们直接拿上次写的自定义控件来用.
  4.实现菜单功能
  5.实现手动调节画布大小的功能
  6.测试 

  实现绘图工具的功能
  为了让代码藕合度小点,稍许用了些设计模式,因为不是很会,所以代码还是有点乱乱的,嘿嘿!关于绘图工具的这些功能块全部写在了DrawTools这个类里.那么在主窗体中,只需要调用这个类来完成绘制就行了,而不需要过多的涉及到具体的绘图代码。绘图工具这个类提供的主要工具就是:铅笔、橡皮、直线、矩形、圆形、实心矩形、实心圆形。关于这些功能块的代码,并不难,只要大家对认真看过前几篇内容,那应该都看得懂。
  这里要注意以下几点:
  1.如何防止记录不必要的绘图过程中的痕迹?
  这个问题在第三篇中有提到过,大家不妨先去看看那一篇。为了让代码看起来可读性高点,我设置了两个Image变量,finishingImg用来保存绘图过程中的痕迹,orginalImg用来保存已完成的绘图过程和初始时的背景图片。
  2.这个类如何与主窗体进行通信?
  当然如果直接将这些功能块写在主窗体中自然没有这个问题。但是那样代码会显得很混杂,如果只是工具代码出现问题就需要改整个项目。我在这里通过定义方法和属性,让主窗体通过给属性赋值将画板画布以及颜色什么的信息传给这个工具类,然后通过调用相应的工具方法来使用这些工具。
  3.关键属性
  要想让这些工具能正常使用,必须传递给他以下几样东西:目标画板(也就是picturebox),绘图颜色,原始画布。


  实现菜单功能
  
  这里就需要我们对文件的操作有一点了解,大家可以去查一下相关资料。
  难点主要就是“打开”这个菜单项的实现
  我们要实现将打开后的图片在修改后重新保存就必须让文件在打开后就能关闭,否则就会因为文件打开而无法覆盖原文件。就会导致编译时弹出“GDI  一般性错误”。所以根据网上其它朋友的做法就是先将打开的图片通过GDI+将图片画到另一个画布上,然后及时关闭打开的图片和用来绘制该图片的画板。详见http://www.wanxin.org/redirect.php?tid=3&goto=lastpost

  private   void  openPic_Click( object  sender, EventArgs e)
        
{
            OpenFileDialog ofd 
= new OpenFileDialog();//实例化文件打开对话框
            ofd.Filter = "JPG|*.jpg|Bmp|*.bmp|所有文件|*.*";//设置对话框打开文件的括展名
            if (ofd.ShowDialog() == DialogResult.OK)
            
{
                Bitmap bmpformfile 
= new Bitmap(ofd.FileName);//获取打开的文件
                panel2.AutoScrollPosition = new Point(0,0);//将滚动条复位
                pbImg.Size = bmpformfile.Size;//调整绘图区大小为图片大小

                reSize.Location 
= new Point(bmpformfile.Width, bmpformfile.Height);//reSize为我用来实现手动调节画布大小用的
                
//因为我们初始时的空白画布大小有限,"打开"操作可能引起画板大小改变,所以要将画板重新传入工具类
                dt.DrawTools_Graphics = pbImg.CreateGraphics();

                Bitmap bmp 
= new Bitmap(pbImg.Width, pbImg.Height);
                Graphics g 
= Graphics.FromImage(bmp);
                g.FillRectangle(
new SolidBrush(pbImg.BackColor), new Rectangle(0, 0, pbImg.Width, pbImg.Height));//不使用这句话,那么这个bmp的背景就是透明的
                g.DrawImage(bmpformfile, 0, 0,bmpformfile.Width,bmpformfile.Height);//将图片画到画板上
                g.Dispose();//释放画板所占资源
                
//不直接使用pbImg.Image = Image.FormFile(ofd.FileName)是因为这样会让图片一直处于打开状态,也就无法保存修改后的图片
                bmpformfile.Dispose();//释放图片所占资源
                g = pbImg.CreateGraphics();
                g.DrawImage(bmp, 
0, 0);
                g.Dispose();
                dt.OrginalImg 
= bmp;
                bmp.Dispose();
                sFileName 
= ofd.FileName;//储存打开的图片文件的详细路径,用来稍后能覆盖这个文件
                ofd.Dispose();

            }

        }

  清除图像其实就是用白色填充整个画布
  其它的都比较简单,这就不具体讲了。

  实现手动调节画布大小
  
网上有人说使用API,但是个人觉得还是使用其它控件帮忙比较简单,至少我们还看得懂。
  思路:放置一个picturebox1(尺寸为5*5),将它固定在主画板的右下角,然后改变鼠标进入时的Cursor为箭头形状,设置鼠标按下移动时的事件,让该picturebox1 跟随鼠标移动。当鼠标松开时,将主画板的右下角坐标调整为picturebox1的坐标。
  下面来看下代码:
  其中的reSize就是我们用来帮忙的picturebox控件 

         private   bool  bReSize  =   false ; // 是否改变画布大小
         private   void  reSize_MouseDown( object  sender, MouseEventArgs e)
        
{
            bReSize 
= true;//当鼠标按下时,说明要开始调节大小
        }


        
private   void  reSize_MouseMove( object  sender, MouseEventArgs e)
        
{
            
if (bReSize)
            
{
                reSize.Location 
= new Point(reSize.Location.X + e.X, reSize.Location.Y + e.Y);

            }

        }


        
private   void  reSize_MouseUp( object  sender, MouseEventArgs e)
        
{
            bReSize 
= false;//大小改变结束
            
//调节大小可能造成画板大小超过屏幕区域,所以事先要设置autoScroll为true.
            
//但是滚动条的出现反而增加了我们的难度,因为滚动条上下移动并不会自动帮我们调整图片的坐标。
            
//这是因为GDI绘图的坐标系不只一个,好像有三个,没有仔细了解,一个是屏幕坐标,一个是客户区坐标,还个是文档坐标。
            
//滚动条的上下移动改变的是文档的坐标,但是客户区坐标不变,而location属性就属于客户区坐标,所以我们直接计算会出现错误
            
//这时我们就需要知道文档坐标与客户区坐标的偏移量,这就是AutoScrollPostion可以提供的

            pbImg.Size 
= new Size(reSize.Location.X - (this.panel2.AutoScrollPosition.X), reSize.Location.Y - (this.panel2.AutoScrollPosition.Y));
            dt.DrawTools_Graphics 
= pbImg.CreateGraphics();//因为画板的大小被改变所以必须重新赋值

            
//另外画布也被改变所以也要重新赋值
            Bitmap bmp = new Bitmap(pbImg.Width, pbImg.Height);
            Graphics g 
= Graphics.FromImage(bmp);
            g.FillRectangle(
new SolidBrush(Color.White), 0, 0, pbImg.Width, pbImg.Height);
            g.DrawImage(dt.OrginalImg, 
0, 0);
            g.Dispose();
            g 
= pbImg.CreateGraphics();
            g.DrawImage(bmp, 
0, 0);
            g.Dispose();
            dt.OrginalImg 
= bmp;

            bmp.Dispose();
        }

  效果如下图(仔细看白色区域的右下角):
  
  此时就可以通过拖动那个小方块来调节图片大小了。
  
  这样,主要的问题差不多已经解决了,但还是有不足这处,欢迎大家提出宝贵的意见。

  绘图工程

其它相关链接:

R语言绘制全球样点分布图完整指南:基于sf与ggplot2 数据可视化是科研与工程中传递空间信息的重要手段,尤其在生态学、地理学等领域,常需将离散样点呈现在全球地图上。R语言凭借其强大的数据处理与可视化生态,成为解决此类问题的首选工具。其中,sf包提供了标准化的空间数据框架,支持投影转换与几何操作;而ggplot2以其灵活的图层语法,可结合rnaturalearth等数据源,高效绘制出版级地图。理解坐标系(如EPSG:4326)与数据清洗是避免点位偏移的关键。从样点导入、底图叠加到分组着色与高清导出,R的完整流程不仅提升了制图效率,更保障了可复现性。无论是物种分布、 阅读详情

相关推荐

c#图片浏览器(实现图片浏览,放大,缩小,删除等功能)

可以简单的实现图片浏览,放大,缩小,删除等功能.

C# GDI+简单绘图(四)

前几篇我已经向大家介绍了如何使用GDI+来绘图,并做了一个截图的实例,这篇我向大家介绍下如何来做一个类似windows画图的工具.   为了完成这个,真是伤透脑筋,因为如果想做一个功能强大的绘图工具,那么单纯掌握GDI还远远不够,我的水平也只能做一个比较简单的绘图工具了.不足之处,欢迎大家讨论!   先来看一下最终效果吧:      主要实现功能:画直线,矩形,橡皮,圆形,

ZLHZHJ的专栏 1107

C#实现的画图板,基本功能都有

C#实现画图,基本功能都有,供需要的朋友参考

c#创建画布_c# GDI+简单绘图(四) 简易画板功能

前几篇我已经向大家介绍了如何使用GDI+来绘图,并做了一个截图的实例,这篇我向大家介绍下如何来做一个类似windows画图的工具.个人认为如果想做一个功能强大的绘图工具,那么单纯掌握GDI还远远不够,我的目前也只能做一个比较简单的绘图工具了.不足之处,欢迎大家讨论!先来看一下最终效果吧:主要实现功能:画直线,矩形,橡皮,圆形,切换颜色,打开图片,保存图片,清除图片,手动调节画布大小;软件刚启动时,...

weixin_33085941的博客 1976

C#编程实现画板功能

C#编程实现画板功能C#编程实现画板功能C#编程实现画板功能

c# Winform 自定义控件 缩放不卡顿。最大可放大至65535。ROI绘制 矩形 圆形 ROI修改

前面通过Picturebox控制图片缩放平移,操作很顺滑,但是放大的时候发现一个问题,放大超过一定尺寸之后画面会非常的卡,可能重绘的面积比较大。 解决思路:放大的过程中,如果图像有超出窗口的部分,则把这部分图像给拆切掉,只显示需要的部分。

UI(6)——C# GDI+简单绘图(四)

  前几篇我已经向大家介绍了如何使用GDI+来绘图,并做了一个截图的实例,这篇我向大家介绍下如何来做一个类似windows画图的工具.   个人认为如果想做一个功能强大的绘图工具,那么单纯掌握GDI还远远不够,我的目前也只能做一个比较简单的绘图工具了.不足之处,欢迎大家讨论!   先来看一下最终效果吧:      主要实现功能:画直线,矩形,橡皮,圆形,切换颜色,打开图片,保存图片,清除图片...

qq_34573534的博客 387

硬件开发流程

研发流程在一个有一定规模的企业中起到了非常重要的作用,也是一个产品或者项目成功量产出货依赖的平台体系,作为工程师如果想要走的更远,就必须了解流程体系,了解如何对产品的开发质量进行更好的管控。...

weixin_44126796的博客 8376

c# GDI+简单绘图(四):实现仿WINDOWS 画板功能

c# GDI+简单绘图(四)  前几篇我已经向大家介绍了如何使用GDI+来绘图,并做了一个截图的实例,这篇我向大家介绍下如何来做一个类似windows画图的工具.  个人认为如果想做一个功能强大的绘图工具,那么单纯掌握GDI还远远不够,我的目前也只能做一个比较简单的绘图工具了.不足之处,欢迎大家讨论!  先来看一下最终效果吧:    主要实现功能:画直线,矩形,橡皮,圆形,切换

蓝嵌软件空间 1507

IEEE Transactions模板中参考文献作者缩写、期刊名缩写

本文章记录如何在IEEE Transactions的模板中,解决参考文献的作者缩写、期刊名字缩写的问题。

weixin_43981621的博客 1万+

LIS3DHTR三轴加速度计Arduino驱动与嵌入式集成指南

加速度计是嵌入式系统中实现运动感知、姿态解算和振动分析的核心传感器。其工作原理基于MEMS微机械结构在惯性力作用下的电容变化,经片内ADC转换为数字信号;I²C接口因其硬件资源占用少、布线简洁,成为低功耗物联网节点的主流通信方式。技术价值体现在高分辨率(12位)、多量程(±2g~±16g)与低功耗(待机电流仅2µA)的平衡,支撑电池供电设备长期运行。典型应用场景包括可穿戴设备的姿态识别、工业预测性维护中的振动监测,以及智能硬件的敲击/跌落检测。本文围绕LIS3DHTR芯片及其Grove模块,详解Arduin

weixin_42584758的博客 594
上一篇: C# GDI+ 简单绘图 (三)
下一篇: DirectX编程:C#中利用Socket实现网络语音通信[初级版本]
csdsuper
博客等级 码龄22年 35粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值