C#中的绘图

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

C#中的绘图
参考:/zihuatanejo/articles/1392689.html
GDI+:Graphics Device Interface Plus也就是图形设备接⼝,提供了各种丰富的图形图像处理功能;在C#.NET中,使⽤GDI+处理⼆维(2D)的图形和图像,使⽤DirectX处理三维(3D)的图形图像,图形图像处理⽤到的主要命名空间是System . Drawing:提供了对GDI+基本图形功能的访问,主要有Graphics类、Bitmap类、从Brush类继承的类、Font类、Icon类、Image类、Pen类、Color类等.
⼤概了解了什么是GDI+后,我们来看⼀下绘图要⽤到的主要⼯具,要画图,肯定要画板吧,在C#中画板可以通过Graphics这个类来创建,有了画板,总得弄个笔什么之类的吧,不然怎么画呀,难不成我们⽤⼿指画.笔⼜可以分好多种类,⽐如铅笔,画刷等.它们的区别主要是铅笔可以⽤来画线条,⽽画刷呢,嘿嘿,⾃⼰考虑下.在c#中我们可以⽤Pen,Brush类来实现类似功能.颜料则⾃然是⽤Color类了.
有了⼯具,我们就可以开始动⼿了!(所需命名空间:using System.Drawing;)
实现效果:在空⽩窗体中画基本图形
准备⼀个画板:
创建⼀个画板主要有3种⽅式:
A: 在窗体或控件的Paint事件中直接引⽤Graphics对象
B: 利⽤窗体或某个控件的CreateGraphics⽅法
C: 从继承⾃图像的任何对象创建Graphics对象
这次我们就先以A为例:
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics; //创建画板,这⾥的画板是由Form提供的.
}
然后,我们要只笔:
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics; //创建画板,这⾥的画板是由Form提供的.
Pen p = new Pen(Color.Blue, 2);//定义了⼀个蓝⾊,宽度为2的画笔
}
接下来我们就可以来画画了.
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics; //创建画板,这⾥的画板是由Form提供的.
Pen p = new Pen(Color.Blue, 2);//定义了⼀个蓝⾊,宽度为的画笔
g.DrawLine(p, 10, 10, 100, 100);//在画板上画直线,起始坐标为(10,10),终点坐标为(100,100)
g.DrawRectangle(p, 10, 10, 100, 100);//在画板上画矩形,起始坐标为(10,10),宽为,⾼为
g.DrawEllipse(p, 10, 10, 100, 100);//在画板上画椭圆,起始坐标为(10,10),外接矩形的宽为,⾼为100
}
1.⾸先我们来看下上⼀⽚中我们使⽤过的Pen.
Pen的属性主要有: Color(颜⾊),DashCap(短划线终点形状),DashStyle(虚线样式),EndCap(线尾形状), StartCap(线头形状),Width(粗细)等.我们可以⽤Pen 来画虚线,带箭头的直线等
Pen p = new Pen(Color.Blue, 5);//设置笔的粗细为,颜⾊为蓝⾊
Graphics g = this.CreateGraphics();
//画虚线
p.DashStyle = DashStyle.Dot;//定义虚线的样式为点
g.DrawLine(p, 10, 10, 200, 10);
//⾃定义虚线
p.DashPattern = new float[] { 2, 1 };//设置短划线和空⽩部分的数组
g.DrawLine(p, 10, 20, 20, 200, 20);
//画箭头,只对不封闭曲线有⽤
p.DashStyle = DashStyle.Solid;//实线
p.EndCap = LineCap.ArrowAnchor;//定义线尾的样式为箭头
g.DrawLine(p, 10, 30, 200, 30);
g.Dispose();
p.Dispose();
2.接下来我们来看下Brush的使⽤
作⽤:我们可以⽤画刷填充各种图形形状,如矩形、椭圆、扇形、多边形和封闭路径等,主要有⼏种不同类型的画刷:
? SolidBrush:画刷最简单的形式,⽤纯⾊进⾏绘制
? HatchBrush:类似于 SolidBrush,但是可以利⽤该类从⼤量预设的图案中选择绘制时要使⽤的图案,⽽不是纯⾊
? TextureBrush:使⽤纹理(如图像)进⾏绘制
? LinearGradientBrush:使⽤沿渐变混合的两种颜⾊进⾏绘制
? PathGradientBrush :基于编程者定义的唯⼀路径,使⽤复杂的混合⾊渐变进⾏绘制
我们这⾥只是简单介绍使⽤其中的⼏种:
Graphics g = this.CreateGraphics();
Rectangle rect = new Rectangle(10, 10, 50, 50);//定义矩形,参数为起点横纵坐标以及其长和宽
//单⾊填充
SolidBrush b1 = new SolidBrush(Color.Blue);//定义单⾊画刷
g.FillRectangle(b1, rect);//填充这个矩形
//字符串
g.DrawString("字符串", new Font("宋体", 10), b1, new PointF(90, 10));
//⽤图⽚填充
TextureBrush b2 = new TextureBrush(Image.FromFile(@"e:picture1.jpg"));
rect.Location = new Point(10, 70);//
rect.Width = 200;//更改这个矩形的宽来
rect.Height = 200;//更改这个矩形的⾼
g.FillRectangle(b2, rect);
//⽤渐变⾊填充
rect.Location = new Point(10, 290);
LinearGradientBrush b3 = new LinearGradientBrush(rect, Color.Yellow , Color.Black , LinearGradientMode.Horizontal);
g.FillRectangle(b3, rect);
3.坐标轴变换
在winform中的坐标轴和我们平时接触的平⾯直⾓坐标轴不同,winform中的坐标轴⽅向完全相反:窗体的左上⾓为原点(0,0),⽔平向左则X 增⼤,垂直下向则Y增⼤
接下来,我们来实际操作下,通过旋转坐标轴的⽅向来画出不同⾓度的图案,或通过更改坐标原点的位置来平衡坐标轴的位置.
Graphics g = this.CreateGraphics();
//单⾊填充
//SolidBrush b1 = new SolidBrush(Color.Blue);//定义单⾊画刷
Pen p = new Pen(Color.Blue,1);
//转变坐标轴⾓度
for (int i = 0; i < 90; i++)
{
g.RotateTransform(i);//每旋转⼀度就画⼀条线
g.DrawLine(p, 0, 0, 100, 0);
g.ResetTransform();//恢复坐标轴坐标
}
//平移坐标轴
g.TranslateTransform(100, 100);
g.DrawLine(p, 0, 0, 100, 0);
g.ResetTransform();
//先平移到指定坐标,然后进⾏度旋转
g.TranslateTransform(100,200);
for (int i = 0; i < 8; i++)
{
g.RotateTransform(45);
g.DrawLine(p, 0, 0, 100, 0);
}
g.Dispose();
4.最后我们来看下Graphics这个画板上我们还可以画什么
其实我们上⾯⽤到的都是在画⼀些简单的图形,直线,矩形,扇形,圆孤等,我们还可以⽤它来绘制图⽚,这可以⽤它的DrawImage⽅法.这⾥我不详细讲解,⼤家有兴趣可以⾃⼰去MSDN了解下.我们后⾯会讲到的截图就会⽤到这个⽅法.
 感谢⼤家的⽀持,这⼏天从早忙到晚,⼀个字累呀现在挺困的,但是⼜不习惯这么早睡觉,哎~~还是利⽤这个时间继续来写第三篇吧.
前两篇已经基本向⼤家介绍了绘图的基本知识.那么,我就⽤我们上两篇所学的,做⼏个例⼦.
我们先来做⼀个简单的----仿QQ截图关于这个的例⼦其实⽹上已经有这⽅⾯的资料了,但是为了⽂章的完整性,还是觉得有必要讲解.
接下来看看这是如何做到的. 
思路:聊天窗体上有⼀个截图按钮,点击按钮后,程序将整个屏幕画在⼀个新的全屏窗体上,然后显⽰这个窗体.因为是全屏的窗体,并且隐藏了菜单栏、⼯具栏等,所以在我们看来就好像是⼀个桌⾯的截图,然后在这个新窗体上画矩形,最后保存矩形中的内容并显⽰在原来的聊天窗体中.
步骤:
A.新建⼀个窗体.命名为Catch.然后设置这个窗体的FormBorderStyle为None,WindowState为Maximized.
B.我们对代码进⾏编辑:
using System;
using System.Collections.Generic;
using ponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Client
{
public partial class Catch : Form
{
public Catch()
{
InitializeComponent();
}
⽤户变量#region ⽤户变量
private Point DownPoint = Point.Empty;//记录⿏标按下坐标,⽤来确定绘图起点
private bool CatchFinished = false;//⽤来表⽰是否截图完成
private bool CatchStart = false;//表⽰截图开始
private Bitmap originBmp;//⽤来保存原始图像
private Rectangle CatchRect;//⽤来保存截图的矩形
#endregion
//窗体初始化操作
private void Catch_Load(object sender, EventArgs e)
{
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | erPaint, true);
this.UpdateStyles();
//以上两句是为了设置控件样式为双缓冲,这可以有效减少图⽚闪烁的问题,关于这个⼤家可以⾃⼰去搜索下
originBmp = new Bitmap(this.BackgroundImage);//BackgroundImage为全屏图⽚,我们另⽤变量来保存全屏图⽚
}
//⿏标右键点击结束截图
private void Catch_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
}
//⿏标左键按下时动作
private void Catch_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (!CatchStart)
{//如果捕捉没有开始
CatchStart = true;
DownPoint = new Point(e.X, e.Y);//保存⿏标按下坐标
}
}
}
private void Catch_MouseMove(object sender, MouseEventArgs e)
{
if (CatchStart)
{//如果捕捉开始
Bitmap destBmp = (Bitmap)originBmp.Clone();//新建⼀个图⽚对象,并让它与原始图⽚相同
Point newPoint = new Point(DownPoint.X, DownPoint.Y);//获取⿏标的坐标
Graphics g = Graphics.FromImage(destBmp);//在刚才新建的图⽚上新建⼀个画板
Pen p = new Pen(Color.Blue,1);
int width = Math.Abs(e.X - DownPoint.X), height = Math.Abs(e.Y - DownPoint.Y);//获取矩形的长和宽
if (e.X < DownPoint.X)
{
newPoint.X = e.X;
}
if (e.Y < DownPoint.Y)
{
newPoint.Y = e.Y;
}
CatchRect = new Rectangle(newPoint,new Size(width,height));//保存矩形
g.DrawRectangle(p,CatchRect);//将矩形画在这个画板上
g.Dispose();//释放⽬前的这个画板
p.Dispose();
Graphics g1 = this.CreateGraphics();//重新新建⼀个Graphics类
//如果之前那个画板不释放,⽽直接g=this.CreateGraphics()这样的话⽆法释放掉第⼀次创建的g,因为只是把地址转到新的g了.如同string⼀样
g1 = this.CreateGraphics();//在整个全屏窗体上新建画板
g1.DrawImage(destBmp,new Point(0,0));//将刚才所画的图⽚画到这个窗体上
//这个也可以属于⼆次缓冲技术,如果直接将矩形画在窗体上,会造成图⽚抖动并且会有⽆数个矩形.
g1.Dispose();
destBmp.Dispose();//要及时释放,不然内存将会被⼤量消耗
}
}
private void Catch_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (CatchStart)
{
CatchStart = false;
CatchFinished = true;
}
}
}
//⿏标双击事件,如果⿏标位于矩形内,则将矩形内的图⽚保存到剪贴板中
private void Catch_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left&&CatchFinished)
{
if (CatchRect.Contains(new Point(e.X, e.Y)))
{
Bitmap CatchedBmp = new Bitmap(CatchRect.Width, CatchRect.Height);//新建⼀个于矩形等⼤的空⽩图⽚
Graphics g = Graphics.FromImage(CatchedBmp);
g.DrawImage(originBmp, new Rectangle(0, 0, CatchRect.Width, CatchRect.Height), CatchRect, GraphicsUnit.Pixel); //把orginBmp中的指定部分按照指定⼤⼩画在画板上
Clipboard.SetImage(CatchedBmp);//将图⽚保存到剪贴板
g.Dispose();
CatchFinished = false;
this.BackgroundImage = originBmp;
CatchedBmp.Dispose();
this.DialogResult = DialogResult.OK;
this.Close();
}
}
}
}
}
C.创建了Catch窗体后,我们在截图按钮(位于聊天窗体上)上加⼊以下事件:
private void bCatch_Click(object sender, EventArgs e)
{if (bCatch_HideCurrent.Checked)
{
this.Hide();//隐藏当前窗体
Thread.Sleep(50);//让线程睡眠⼀段时间,窗体消失需要⼀点时间
Catch CatchForm = new Catch();
Bitmap CatchBmp = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);//新建⼀个和屏幕⼤⼩相同的图⽚
Graphics g = Graphics.FromImage(CatchBmp);
g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height));//保存全屏图⽚
CatchForm.BackgroundImage = CatchBmp;//将Catch窗体的背景设为全屏时的图⽚
if (CatchForm.ShowDialog() == DialogResult.OK)
{//如果Catch窗体结束,就将剪贴板中的图⽚放到信息发送框中
IDataObject iData = Clipboard.GetDataObject();
DataFormats.Format myFormat = DataFormats.GetFormat(DataFormats.Bitmap);
if (iData.GetDataPresent(DataFormats.Bitmap))
{
richtextbox1.Paste(myFormat);
Clipboard.Clear();//清除剪贴板中的对象
}
this.Show();//重新显⽰窗体
}
}
}
这样我们的截图功能便完成了.
我想对于初学者来说如何消去第⼀次绘制的图⽚是个⽐较困难的问题.如果没有采取措施,你会发现只要你⿏标移动,就会画⼀个矩形,这样便会出现N多的矩形,⽽我们只是要最后的那⼀个.
⼀般解决这种问题的⽅法有两种:
1.就是在绘制第⼆个图形时,我们先⽤与底⾊相同的颜⾊将上次绘制的图形重新绘制⼀下.但这往往需要底⾊为纯⾊时使⽤.
2.我们并不直接将图形画在画板上,我们⽤⼀个图⽚A来保存原画板上的图⽚.然后再新建⼀个与图⽚A相同的图⽚B,将我们要绘制的图形画在该图⽚B上,然后再将该图⽚B画在画板上.这样图⽚A并没有被改变.于是第⼆次画的时候我们还是同样新建⼀个与图⽚A相同的图⽚进⾏绘制.那么上⼀次的图形就不会被保留下来.问题也就解决了.
下⼀次,向⼤家介绍如何做⼀个仿windows画板的程序.
前⼏篇我已经向⼤家介绍了如何使⽤GDI+来绘图,并做了⼀个截图的实例,这篇我向⼤家介绍下如何来做⼀个类似windows画图的⼯具.
主要实现功能:画直线,矩形,橡⽪,圆形,切换颜⾊,打开图⽚,保存图⽚,清除图⽚,⼿动调节画布⼤⼩;软件刚启动时,为⼀张空⽩画布,我们可以直接在画布上绘图,也可以通过菜单中的“打开”,导⼊⼀张图⽚,然后我们就可以在这张图⽚上进⾏绘制。

平台:VS2005 WINFORM
由于代码过多,在这⾥只简要介绍下制作步骤,提供⼤家⼯程下载.
1.对整个界⾯进⾏布局.
2.实现绘图⼯具的功能
3.实现颜⾊拾取的功能,这⾥我们直接拿上次写的⾃定义控件来⽤.
4.实现菜单功能
5.实现⼿动调节画布⼤⼩的功能
6.测试
实现绘图⼯具的功能
为了让代码藕合度⼩点,稍许⽤了些设计模式,因为不是很会,所以代码还是有点乱乱的,绘图⼯具的这些功能块全部写在了DrawTools这个类⾥.那么在主窗体中,只需要调⽤这个类来完成绘制就⾏了,⽽不需要过多的涉及到具体的绘图代码。

绘图⼯具这个类提供的主要⼯具就是:铅笔、橡⽪、直线、矩形、圆形、实⼼矩形、实⼼圆形。

关于这些功能块的代码,并不难,只要⼤家对认真看过前⼏篇内容,那应该都看得懂。

这⾥有⼏点要注意:
1.如何防⽌记录不必要的绘图过程中的痕迹?
这个问题在第三篇中有提到过,⼤家不妨先去看看那⼀篇。

为了让代码看起来可读性⾼点,我设置了两个Image变量,finishingImg⽤来保存绘图过程中的痕迹,orginalImg⽤来保存已完成的绘图过程和初始时的背景图⽚。

2.这个类如何与主窗体进⾏通信?
当然如果直接将这些功能块写在主窗体中⾃然没有这个问题。

但是那样代码会显得很混杂,如果只是⼯具代码出现问题就需要改整个项⽬。

我在这⾥通过定义⽅法和属性,让主窗体通过给属性赋值将画板画布以及颜⾊什么的信息传给这个⼯具类,然后通过调⽤相应的⼯具⽅法来使⽤这些⼯具。

3.关键属性
要想让这些⼯具能正常使⽤,必须传递给他以下⼏样东西:⽬标画板(也就是picturebox),绘图颜⾊,原始画布。

实现菜单功能
这⾥就需要我们对⽂件的操作有⼀点了解,⼤家可以去查⼀下相关资料。

难点主要就是“打开”这个菜单项的实现
我们要实现将打开后的图⽚在修改后重新保存就必须让⽂件在打开后就能关闭,否则就会因为⽂件打开⽽⽆法覆盖原⽂件。

就会导致编译时弹出“GDI ⼀般性错误”。

所以根据⽹上其它朋友的做法就是先将打开的图⽚通过GDI+将图⽚画到另⼀个画布上,然后及时关闭打开的图⽚和⽤来绘制该图⽚的画板。

详见/redirect.php?tid=3&goto=lastpost
private void openPic_Click(object sender, EventArgs e)
这⾥就需要我们对⽂件的操作有⼀点了解,⼤家可以去查⼀下相关资料。

难点主要就是“打开”这个菜单项的实现
我们要实现将打开后的图⽚在修改后重新保存就必须让⽂件在打开后就能关闭,否则就会因为⽂件打开⽽⽆法覆盖原⽂件。

就会导致编译时弹出“GDI ⼀般性错误”。

所以根据⽹上其它朋友的做法就是先将打开的图⽚通过GDI+将图⽚画到另⼀个画布上,然后及时关闭打开的图⽚和⽤来绘制该图⽚的画板。

详见/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();
inalImg = 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.
//但是滚动条的出现反⽽增加了我们的难度,因为滚动条上下移动并不会⾃动帮我们调整图⽚的坐标。

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(inalImg, 0, 0);
g.Dispose();
g = pbImg.CreateGraphics();
g.DrawImage(bmp, 0, 0);
g.Dispose();
inalImg = bmp;
bmp.Dispose();
}
此时就可以通过拖动那个⼩⽅块来调节图⽚⼤⼩了。

相关文档
最新文档