前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【愚公系列】2024年01月 GDI+绘图专题(裁剪、变换、重绘)

【愚公系列】2024年01月 GDI+绘图专题(裁剪、变换、重绘)

原创
作者头像
愚公搬代码
发布2024-01-11 23:41:28
2591
发布2024-01-11 23:41:28
举报
文章被收录于专栏:历史专栏历史专栏

🏆 作者简介,愚公搬代码 🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。 🏆《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。

🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。

🏆🎉欢迎 👍点赞✍评论⭐收藏

🚀前言

裁剪(Clipping)指的是将图像或元素的一部分进行裁剪,只显示所需区域,而隐藏不需要的部分。

变换(Transforming)指的是将图像或元素进行缩放、旋转、平移等操作,以改变其大小、方向或位置。

重绘(Repainting)指的是根据新的布局或者样式信息,重新绘制图像或元素的外观。当元素的位置、大小、样式发生变化时,需要重新绘制来更新外观。

这些操作常常在图形处理、界面设计、游戏开发等领域中使用。

🚀一、裁剪

🔎1.SetClip

Graphics.SetClip 方法是 GDI+ 绘图中的一个方法,它可以设置裁剪区域,以便在绘制图形时只绘制指定区域内的部分。该方法可以接受多种类型的参数来指定裁剪区域,例如一个矩形、一个多边形、一个路径和一个区域等。

下面是一个使用 Graphics.SetClip 方法设置裁剪区域的示例:

代码语言:csharp
复制
private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics graphics = e.Graphics;

    // 绘制矩形
    Rectangle rect = new Rectangle(10, 10, 100, 100);
    graphics.DrawRectangle(Pens.Black, rect);

    // 设置裁剪区域为矩形的一半
    Rectangle clipRect = new Rectangle(10, 10, 50, 100);
    Region region = new Region(clipRect);
    graphics.SetClip(region, CombineMode.Replace);

    // 绘制椭圆
    Rectangle ellipseRect = new Rectangle(50, 50, 100, 50);
    graphics.FillEllipse(Brushes.Red, ellipseRect);
}

private void button1_Click(object sender, EventArgs e)
{
    // 重绘图形
    Invalidate();
}

在上述代码中,首先绘制了一个矩形,然后使用 Region 对象指定了一个裁剪区域。接着使用 Graphics.SetClip 方法将该区域设置为裁剪区域,只有该区域内的图形才会被绘制。在此之后绘制了一个椭圆,它只被绘制在了矩形的左半部分区域内。

需要注意的是,裁剪区域可以通过多次调用 Graphics.SetClip 方法来叠加,也可以通过 Graphics.ResetClip 方法清除。而裁剪模式则可以用 CombineMode 枚举类型来指定,例如 CombineMode.ReplaceCombineMode.IntersectCombineMode.UnionCombineMode.Exclude 等等。

🚀二、重绘

🔎1.Invalidate

Invalidate是在Graphics中使用的方法之一,它用于指示Graphics对象无效并需要重新绘制。当调用该方法时,Graphics对象将被标记为需要重新绘制,在屏幕更新之前将使用新的绘图数据更新。使用Invalidate方法是在屏幕上显示动态图形的一种常见方法。调用Invalidate方法后,必须等待下一次屏幕更新才能看到更新后的图形。

与之相对应的方法是Refresh方法。Refresh方法会立即重绘Graphics对象,而不是等待下一次屏幕更新。因此,如果您需要立即更新图形,可以使用Refresh方法。

如果您正在处理与用户交互的图形,例如响应鼠标单击事件,则可能需要使用Invalidate方法来更新屏幕上的图形,而不是使用Refresh。如果使用Refresh,则可能会在用户交互时引起闪烁或不必要的图形更新。

以下是一个简单的案例,演示如何在WinForm中使用Invalidate方法进行GDI+绘图的重绘:

代码语言:csharp
复制
//在窗体中定义一个标志位,用于指示是否需要重新绘制图形
private bool isNeedToRedraw = false;

//在窗体中定义一个方法,用于绘制图形
private void DrawGraphics(Graphics g)
{
   //绘制代码
}

//在窗体的Paint事件中调用DrawGraphics方法进行绘制
private void Form1_Paint(object sender, PaintEventArgs e)
{
   if (isNeedToRedraw)
   {
      DrawGraphics(e.Graphics);
   }
}

//在窗体的其他事件中调用Invalidate方法进行图形更新
private void button1_Click(object sender, EventArgs e)
{
   isNeedToRedraw = true;
   this.Invalidate();
}

//在窗体的Load事件中设置双缓冲
private void Form1_Load(object sender, EventArgs e)
{
   this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer | ControlStyles.UserPaint, true);
   this.UpdateStyles();
}

在上述代码中,我们定义了一个标志位isNeedToRedraw,用于指示是否需要重新绘制图形。在窗体的Paint事件中,如果标志位为True,则调用DrawGraphics方法进行绘制。

在窗体的其他事件中,例如按钮单击事件,我们将标志位设置为True,并调用Invalidate方法来更新图形。通过这种方式,我们可以确保只有在需要更新图形时才执行绘图操作,从而提高了程序的效率。

为了避免出现图形闪烁的情况,我们在窗体的Load事件中设置了双缓冲。这样可以在绘制时使用一个缓存图像,等绘制完成后再将整个图像一次性绘制到屏幕上,从而消除了图形闪烁的问题。

🚀三、变换

🔎1.缩放

GDI+通过ScaleTransform方法实现图形缩放,该方法可以在水平方向和垂直方向上分别缩放图形。具体使用方法如下:

代码语言:csharp
复制
//在Graphics对象上调用ScaleTransform方法
graphics.ScaleTransform(float scaleX, float scaleY);

其中,scaleX和scaleY分别表示水平方向和垂直方向上的缩放比例,它们的取值范围是0到正无穷大的浮点数。

下面是一个简单的案例,演示如何使用ScaleTransform方法实现图形的缩放:

代码语言:csharp
复制
//创建一个Graphics对象
Graphics g = e.Graphics;

//设置缩放比例
float scaleX = 2.0f;
float scaleY = 1.5f;

g.DrawRectangle(Pens.Red, 10, 10, 50, 50);

//调用ScaleTransform方法进行缩放
g.ScaleTransform(scaleX, scaleY);

//绘制图形
g.DrawLine(Pens.Black, 0, 0, 100, 100);
g.DrawRectangle(Pens.Red, 10, 10, 50, 50);

在上述代码中,我们在窗体的Paint事件中创建了一个Graphics对象,然后设置了水平方向上的缩放比例为2,垂直方向上的缩放比例为1.5。

接着,我们调用Graphics对象的ScaleTransform方法进行缩放,并使用DrawLine和DrawRectangle方法绘制了一条直线和一个矩形。在绘制时,由于已经对图形进行了缩放,因此绘制出的直线和矩形大小与原来的大小不同。

需要注意的是,ScaleTransform方法是矩阵变换的一种,因此会对Graphics对象上所有的绘制操作产生影响,包括线条粗细、字体大小等。如果需要还原Graphics对象的状态,可以使用ResetTransform方法,该方法会将Graphics对象的矩阵变换重置为默认状态。

🔎2.平移

在Graphics中,可以使用TranslateTransform方法来实现平移。该方法可将平移量添加到当前的坐标系中,从而实现平移效果。

下面是一个简单的示例代码:

代码语言:csharp
复制
//创建一个Graphics对象
Graphics g = e.Graphics;

g.DrawRectangle(Pens.Red, 10, 10, 50, 50);

//调用ScaleTransform方法进行缩放
g.TranslateTransform(100, 50);

//绘制图形
g.DrawLine(Pens.Black, 0, 0, 100, 100);
g.DrawRectangle(Pens.Red, 10, 10, 50, 50);

使用TranslateTransform方法将坐标系平移100个单位的水平方向和50个单位的垂直方向。最后,在平移后的位置绘制一个矩形。注:实际上这里的矩形的左上角坐标为原点坐标(0,0),但是因为平移了 (100,50) 的距离,所以它在屏幕上显示的位置应该是 (100,50)。最后,释放Graphics对象的资源。

通过修改TranslateTransform方法中的参数,可以实现不同的平移效果。例如,如果将平移量改为(-50, 100),则坐标系将向上平移50个单位,向左平移100个单位。

代码语言:csharp
复制
g.TranslateTransform(-50, 100);

需要注意的是,TranslateTransform方法不会改变绘图对象的位置,而是会改变坐标系的位置。如果要将绘图对象移动到新的位置,应该使用其他的绘图方法或属性,例如DrawRectangle方法中的x和y参数。

🔎3.旋转

在使用Graphics进行绘图时,可以使用RotateTransform方法实现旋转操作。该方法可以应用一个旋转变换到当前的Graphics对象上,从而改变绘制的方向。

具体操作步骤如下:

  1. 创建一个Graphics对象,例如:Graphics g = this.CreateGraphics();
  2. 调用RotateTransform方法实现旋转操作,例如:g.RotateTransform(45);

该方法需要一个参数,表示旋转的角度。这里的参数为45度,表示将当前的Graphics对象旋转45度。

  1. 在旋转后的Graphics对象上进行绘制操作,例如:g.DrawLine(pen, 0, 0, 100, 0);

这里使用DrawLine方法在旋转后的Graphics对象上绘制一条线段,起点坐标为(0,0),终点坐标为(100,0)。

  1. 重置Graphics对象的变换,以便后续的绘制操作不受影响,例如:g.ResetTransform();

这里使用ResetTransform方法重置Graphics对象的变换,以便后续的绘制操作不受影响。

完整的代码示例如下:

代码语言:csharp
复制
//创建一个Graphics对象
Graphics g = e.Graphics;

g.DrawRectangle(Pens.Red, 10, 10, 50, 50);
g.TranslateTransform(100, 50);
//调用ScaleTransform方法进行缩放
g.RotateTransform(45);

//绘制图形
g.DrawLine(Pens.Black, 0, 0, 100, 100);
g.DrawRectangle(Pens.Red, 10, 10, 50, 50);

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 🚀前言
  • 🚀一、裁剪
    • 🔎1.SetClip
    • 🚀二、重绘
      • 🔎1.Invalidate
      • 🚀三、变换
        • 🔎1.缩放
          • 🔎2.平移
            • 🔎3.旋转
            相关产品与服务
            图数据库 KonisGraph
            图数据库 KonisGraph(TencentDB for KonisGraph)是一种云端图数据库服务,基于腾讯在海量图数据上的实践经验,提供一站式海量图数据存储、管理、实时查询、计算、可视化分析能力;KonisGraph 支持属性图模型和 TinkerPop Gremlin 查询语言,能够帮助用户快速完成对图数据的建模、查询和可视化分析。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档