服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C# 使用 GDI+ 实现添加中心旋转(任意角度)的文字

C# 使用 GDI+ 实现添加中心旋转(任意角度)的文字

2022-02-22 14:18Dandelion_drq C#

这篇文章主要介绍了C# 使用 GDI+ 实现添加中心旋转(任意角度)的文字,需要的朋友可以参考下

前言

这篇文章是 gdi+ 总结系列的第三篇,如果对 gdi+ 的基础使用不熟悉的朋友可以先看第一篇文章《c# 使用 gdi+ 画图》。

需求

需求是要实现给图片添加任意角度旋转的文字,文字的旋转中心要是在文字区域中央,就像 css 的 rotate 函数一样的效果。如下:

C# 使用 GDI+ 实现添加中心旋转(任意角度)的文字

分析&思路

graphics 类有个 rotatetransform 方法,可以传入任意角度的值来旋转画板。但是这个方法的旋转中心是画板的左上角,所以直接单单用这个方法不能满足我们的需求。此外, graphics 类还有个 translatetransform 方法可以改变坐标的原点,而且这个方法是沿着矩形的x,y轴平移的,即就算图片旋转了一定的角度后,再调用 translatetransform 方法,它还是沿着x,y轴平移。于是通过以下三个步骤即可实现图片中心旋转。

  1. 把画板(graphics对象)原点平移到矩形中心位置(x, y)
  2. 在(x, y)位置绕原点旋转画板n度
  3. 画板退回(-x, -y)的距离

还是看不懂的同学看下面的图应该就明白了

C# 使用 GDI+ 实现添加中心旋转(任意角度)的文字

明白了原理,那不容易推断出,如果要旋转的中心不是图片中心而是文字中心,那步骤还是一样的,只是把(x, y)改为文字中心的坐标就好了。

除了上面说的方法,其实还有一个方法可以实现中心旋转,那就是使用 matrix 类。 matrix 类的 rotateat 方法可以指定矩阵旋转的中心位置。

?
1
2
3
4
5
6
7
8
9
10
11
12
//
 // 摘要:
 //  沿 point 参数中指定的点并通过预先计算该旋转,来顺时针旋转此 system.drawing.drawing2d.matrix。
 //
 // 参数:
 // angle:
 //  旋转角度(范围)(单位:度)。
 //
 // point:
 //  一个 system.drawing.pointf,表示旋转中心。
 [targetedpatchingoptout("performance critical to inline this type of method across ngen image boundaries")]
 public void rotateat(float angle, pointf point);

graphics 类的 transform 属性返回的就是 matrix 对象,该属性可以 get 、 set 。因此我们先获取原来的画板的矩阵,然后使用 rotateat 方法旋转该矩阵,再把旋转后的矩阵赋值给画板就好了。

具体实现

添加任意角度文字方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/// <summary>
/// 图片添加任意角度文字(文字旋转是中心旋转,角度顺时针为正)
/// </summary>
/// <param name="imgpath">图片路径</param>
/// <param name="locationlefttop">文字左上角定位(x1,y1)</param>
/// <param name="fontsize">字体大小,单位为像素</param>
/// <param name="text">文字内容</param>
/// <param name="angle">文字旋转角度</param>
/// <param name="fontname">字体名称</param>
/// <returns>添加文字后的bitmap对象</returns>
public bitmap addtext(string imgpath, string locationlefttop, int fontsize, string text, int angle = 0, string fontname = "华文行楷")
{
 image img = image.fromfile(imgpath);
 int width = img.width;
 int height = img.height;
 bitmap bmp = new bitmap(width, height);
 graphics graphics = graphics.fromimage(bmp);
 // 画底图
 graphics.drawimage(img, 0, 0, width, height);
 font font = new font(fontname, fontsize, graphicsunit.pixel);
 sizef sf = graphics.measurestring(text, font); // 计算出来文字所占矩形区域
 // 左上角定位
 string[] location = locationlefttop.split(',');
 float x1 = float.parse(location[0]);
 float y1 = float.parse(location[1]);
 // 进行文字旋转的角度定位
 if (angle != 0)
 {
  #region 法一:translatetransform平移 + rotatetransform旋转
  /*
   * 注意:
   * graphics.rotatetransform的旋转是以graphics对象的左上角为原点,旋转整个画板的。
   * 同时x,y坐标轴也会跟着旋转。即旋转后的x,y轴依然与矩形的边平行
   * 而graphics.translatetransform方法,是沿着x,y轴平移的
   * 因此分三步可以实现中心旋转
   * 1.把画板(graphics对象)平移到旋转中心
   * 2.旋转画板
   * 3.把画板平移退回相同的距离(此时的x,y轴仍然是与旋转后的矩形平行的)
   */
  //// 把画板的原点(默认是左上角)定位移到文字中心
  //graphics.translatetransform(x1 + sf.width / 2, y1 + sf.height / 2);
  //// 旋转画板
  //graphics.rotatetransform(angle);
  //// 回退画板x,y轴移动过的距离
  //graphics.translatetransform(-(x1 + sf.width / 2), -(y1 + sf.height / 2));
  #endregion
  #region 法二:矩阵旋转
  matrix matrix = graphics.transform;
  matrix.rotateat(angle, new pointf(x1 + sf.width / 2, y1 + sf.height / 2));
  graphics.transform = matrix;
  #endregion
 }
 // 写上自定义角度的文字
 graphics.drawstring(text, font, new solidbrush(color.black), x1, y1);
 graphics.dispose();
 img.dispose();
 return bmp;
}

ps:这里简单解释一下为什么文字中心是 (x1 + sf.width / 2, y1 + sf.height / 2) ,因为 (x, y) 是左上角,而 sf.width 、 sf.height 是文字矩形区域宽、高。如图:

C# 使用 GDI+ 实现添加中心旋转(任意角度)的文字

测试调用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private static void main(string[] args)
{
 try
 {
  console.writeline("start drawing ...");
  drawingentity drawing = new drawingentity();
  system.drawing.bitmap bmp = drawing.addtext(@"d:\test\1.png", "176.94,150.48", 66, "写点啥好呢", 30);
  bmp.save(@"d:\test\output.png");
  bmp.dispose();
  console.writeline("done!");
 }
 catch (system.exception ex)
 {
  console.writeline(ex.tostring());
 }
 finally
 {
  system.console.writeline("\npress any key to continue ...");
  system.console.readkey();
 }
}

最终效果

没有旋转时

C# 使用 GDI+ 实现添加中心旋转(任意角度)的文字

中心旋转30度

C# 使用 GDI+ 实现添加中心旋转(任意角度)的文字

总结

以上所述是小编给大家介绍的c# 使用 gdi+ 实现添加中心旋转(任意角度)的文字,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!

原文链接:http://www.cnblogs.com/dandelion-drq/p/csharp_use_gdiplus_to_rotate_text.html

延伸 · 阅读

精彩推荐
  • C#VS2012 程序打包部署图文详解

    VS2012 程序打包部署图文详解

    VS2012虽然没有集成打包工具,但它为我们提供了下载的端口,需要我们手动安装一个插件InstallShield。网上有很多第三方的打包工具,但为什么偏要使用微软...

    张信秀7712021-12-15
  • C#C#微信公众号与订阅号接口开发示例代码

    C#微信公众号与订阅号接口开发示例代码

    这篇文章主要介绍了C#微信公众号与订阅号接口开发示例代码,结合实例形式简单分析了C#针对微信接口的调用与处理技巧,需要的朋友可以参考下...

    smartsmile20127762021-11-25
  • C#利用C#实现网络爬虫

    利用C#实现网络爬虫

    这篇文章主要介绍了利用C#实现网络爬虫,完整的介绍了C#实现网络爬虫详细过程,感兴趣的小伙伴们可以参考一下...

    C#教程网11852021-11-16
  • C#C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    这篇文章主要介绍了C#设计模式之Strategy策略模式解决007大破密码危机问题,简单描述了策略模式的定义并结合加密解密算法实例分析了C#策略模式的具体使用...

    GhostRider10972022-01-21
  • C#如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    这篇文章主要给大家介绍了关于如何使用C#将Tensorflow训练的.pb文件用在生产环境的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴...

    bbird201811792022-03-05
  • C#深入理解C#的数组

    深入理解C#的数组

    本篇文章主要介绍了C#的数组,数组是一种数据结构,详细的介绍了数组的声明和访问等,有兴趣的可以了解一下。...

    佳园9492021-12-10
  • C#SQLite在C#中的安装与操作技巧

    SQLite在C#中的安装与操作技巧

    SQLite,是一款轻型的数据库,用于本地的数据储存。其优点有很多,下面通过本文给大家介绍SQLite在C#中的安装与操作技巧,感兴趣的的朋友参考下吧...

    蓝曈魅11162022-01-20
  • C#三十分钟快速掌握C# 6.0知识点

    三十分钟快速掌握C# 6.0知识点

    这篇文章主要介绍了C# 6.0的相关知识点,文中介绍的非常详细,通过这篇文字可以让大家在三十分钟内快速的掌握C# 6.0,需要的朋友可以参考借鉴,下面来...

    雨夜潇湘8272021-12-28