c# GDI+简单绘图(四)
前几篇我已经向大家介绍了如何使用GDI+来绘图,并做了一个截图的实例,这篇我向大家介绍下如何来做一个类似windows画图的工具.
个人认为如果想做一个功能强大的绘图工具,那么单纯掌握GDI还远远不够,我的目前也只能做一个比较简单的绘图工具了.不足之处,欢迎大家讨论!
先来看一下最终效果吧:
主要实现功能:画直线,矩形,橡皮,圆形,切换颜色,打开图片,保存图片,清除图片,手动调节画布大小;软件刚启动时,为一张空白画布,我们可以直接在画布上绘画,也可以通过菜单中的“打开”,导入一张图片,然后我们就可以在这张图片上进行绘制。
平台:VS2005 WINFORM
由于代码过多,在这里只简要介绍下制作步骤,提供大家工程下载.
1.对整个界面进行布局.
2.实现绘图工具的功能
3.实现颜色拾取的功能,这里我们直接拿上次写的自定义控件来用.
4.实现菜单功能
5.实现手动调节画布大小的功能
6.测试
实现绘图工具的功能
为了让代码藕合度小点,稍许用了些设计模式,因为不是很会,所以代码还是有点乱乱的,嘿嘿!关于绘图工具的这些功能块全部写在了DrawTools这个类里.那么在主窗体中,只需要调用这个类来完成绘制就行了,而不需要过多的涉及到具体的绘图代码。绘图工具这个类提供的主要工具就是:铅笔、橡皮、直线、矩形、圆形、实心矩形、实心圆形。关于这些功能块的代码,并不难,只要大家对认真看过前几篇内容,那应该都看得懂。
这里要注意以下几点:
1.如何防止记录不必要的绘图过程中的痕迹?
这个问题在第三篇中有提到过,大家不妨先去看看那一篇。为了让代码看起来可读性高点,我设置了两个Image变量,finishingImg用来保存绘图过程中的痕迹,orginalImg用来保存已完成的绘图过程和初始时的背景图片。
2.这个类如何与主窗体进行通信?
当然如果直接将这些功能块写在主窗体中自然没有这个问题。但是那样代码会显得很混杂,如果只是工具代码出现问题就需要改整个项目。我在这里通过定义方法和属性,让主窗体通过给属性赋值将画板画布以及颜色什么的信息传给这个工具类,然后通过调用相应的工具方法来使用这些工具。
3.关键属性
要想让这些工具能正常使用,必须传递给他以下几样东西:目标画板(也就是picturebox),绘图颜色,原始画布。
实现菜单功能
这里就需要我们对文件的操作有一点了解,大家可以去查一下相关资料。
难点主要就是“打开”这个菜单项的实现
我们要实现将打开后的图片在修改后重新保存就必须让文件在打开后就能关闭,否则就会因为文件打开而无法覆盖原文件。就会导致编译时弹出“GDI 一般性错误”。所以根据网上其它朋友的做法就是先将打开的图片通过GDI+将图片画到另一个画布上,然后及时关闭打开的图片和用来绘制该图片的画板。
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(); }
效果如下图(仔细看白色区域的右下角):
此时就可以通过拖动那个小方块来调节图片大小了。
这样,主要的问题差不多已经解决了,但还是有不足这处,欢迎大家提出宝贵的意见。
更多c# GDI+简单绘图(四)相关文章请关注PHP中文网!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Cet article explore les défis des déréférences du pointeur nul dans C. Il soutient que le problème n'est pas nul lui-même, mais son utilisation abusive. L'article détaille les meilleures pratiques pour prévenir les déréférences, y compris les contrôles de pré-déréférence, le pointeur initiali

Cet article explique comment créer de nouvelles caractères en C en C en utilisant la séquence \ n Escape dans printf et met des fonctions. Il détaille les fonctionnalités et fournit des exemples de code démontrant son utilisation pour les ruptures de ligne en sortie.

Cet article guide les débutants sur le choix d'un compilateur C. Il fait valoir que le CCG, en raison de sa facilité d'utilisation, de sa large disponibilité et de ses vastes ressources, est la meilleure pour les débutants. Cependant, il compare également GCC, Clang, MSVC et TCC, mettant en évidence leur différenciation

Cet article met l'accent sur l'importance continue de Null dans la programmation C moderne. Malgré les progrès, NULL reste crucial pour la gestion explicite du pointeur, empêchant les défauts de segmentation en marquant l'absence d'une adresse mémoire valide. Meilleur prac

Cet article passe en revue les compilateurs C en ligne pour les débutants, en se concentrant sur la facilité d'utilisation et les capacités de débogage. Onlinegdb et Rep.Il sont mis en évidence pour leurs interfaces conviviales et leurs outils de débogage utiles. Autres options comme Programiz et Compil

Cet article compare les plateformes de programmation C en ligne, mettant en évidence les différences de fonctionnalités telles que les outils de débogage, les fonctionnalités IDE, la conformité standard et les limites de mémoire / d'exécution. Il soutient que la "meilleure" plate-forme dépend des besoins des utilisateurs,

Cet article traite de la copie de code efficace dans les Cides. Il souligne que la copie est une fonction IDE, pas une fonctionnalité de compilateur, et détaille des stratégies pour une efficacité améliorée, y compris l'utilisation d'outils de sélection IDE, le pliage de code, la recherche / remplacer, Templa

Cet article dépanne les fenêtres de sortie manquantes dans la compilation du programme C. Il examine des causes telles que le non-exécution de l'exécutable, des erreurs de programme, des paramètres de compilateur incorrects, des processus de fond et une terminaison rapide du programme. Les solutions impliquent ch
