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


需求

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


分析&思路

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

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

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

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

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

    //// 摘要://     沿 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 对象,该属性可以 getset。因此我们先获取原来的画板的矩阵,然后使用 RotateAt 方法旋转该矩阵,再把旋转后的矩阵赋值给画板就好了。


具体实现

  • 添加任意角度文字方法
    /// <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.Widthsf.Height 是文字矩形区域宽、高。如图:

  • 测试调用
    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();}}

最终效果

  • 没有旋转时

  • 中心旋转30度


一个思考

讲完了大家来思考一个问题,如果我想做图片绕任意位置为中心进行旋转应该怎么做呢?相信看完了上面的代码大家应该都会了吧。


参考文章:

C#中基于GDI+(Graphics)图像处理系列之任意角度旋转图像

C#利用GDI+绘制旋转文字,矩形内可以根据布局方式排列文本


系列其他文章:

C# 使用 GDI+ 画图

C# 使用 GDI+ 给图片添加文字,并使文字自适应矩形区域

转载于:https://www.cnblogs.com/dandelion-drq/p/csharp_use_gdiplus_to_rotate_text.html

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

  1. opencv图片旋转关于中心旋转任意角度与坐标转换

    如下例子,实现图片关于中心旋转任意角度,及坐标变换 import os import os.path import cv2 import numpy as np from math import co ...

  2. c++实现图像旋转任意角度

    图形图像处理-之-任意角度的高质量的快速的图像旋转 上篇 纯软件的任意角度的快速旋转                                 HouSisong@GMail.com   200 ...

  3. JQuery插件让图片旋转任意角度且代码极其简单 - 摘自网友

    JQuery插件让图片旋转任意角度且代码极其简单 2012-04-01 09:57:03     我来说两句       收藏    我要投稿 引入下方的jquery.rotate.js文件,然后通过 ...

  4. PDF任意页旋转任意角度

    使用软件:Adobe Acrobat Pro DC.Enfocus PitStop Pro插件 1.打开PDF文件 2.在左侧选中右键可以旋转固定角度 3.如果要旋转任意角度,Alt+Ctrl+G  ...

  5. JQuery插件让图片旋转任意角度且代码极其简单

    引入下方的jquery.rotate.js文件,然后通过$("选择器").rotate(角度);可以旋转任意角度, 例如$("#rotate-image").r ...

  6. 利用Matlab将任意曲线旋转任意角度

    利用Matlab将任意曲线旋转任意角度 公式计算 数据 matlab代码 结果 公式计算 对于如上图所示的任意曲线,需要绕固定点O旋转某一角度,取曲线上任意一点A计算旋转后的坐标值. 设OA的长度为L ...

  7. Unity物体围绕中中心旋转加角度

    Unity物体围绕中中心旋转加角度 ```csharp using System.Collections; using System.Collections.Generic; using UnityE ...

  8. matlab控制三角形绕原点旋转任意角度

    项目中遇到一个问题,需要把正三角形绕原点旋转任意角度,平时操作图片的时候,顺便旋转,感觉好像很简单,但是自己去做的时候还是有些困难. 我觉得旋转的难点在于由原始点计算新的目标点上,因为你需要考虑点位于 ...

  9. Qt QPixmap旋转任意角度

    效果 使用 QPixmap pix2 = rotateImageWithTransform(pix1, 30); 源码 // 旋转图片任意角度 QPixmap rotateImageWithTrans ...

最新文章

  1. centos6.8 配置 tomcat
  2. 解决fatal: 不是一个 git 仓库(或者任何父目录)的方法
  3. Tkinter的OptionMenu组件
  4. jQuery clearQueue
  5. [Android源码]Android源码之高仿飞鸽传书WIFI热点搜索与创建(一)
  6. Leetcode--24. 两两交换链表中的结点
  7. layer文件ajax上传,layer弹出层数据传输到content里面
  8. java多线程中出现的异常分别有哪些_java多线程试题
  9. c语言五子棋评估函数,简易五子棋评估函数
  10. 设计模式1【续】:动态设定行为
  11. k8s容器灰度发布最佳实践(基于spinnaker)
  12. py获取前端的参数_鹅厂技术说 | 深入理解前端性能监控
  13. karto探秘之slam_karto
  14. Windows 7操作系统
  15. Science:无氧世界的古菌氨氧化
  16. 签字后被开除_我的易到经历以及老易到员工是如何被乐视派驻高管从易到开除的...
  17. ionic入门教程第十一课-简要说明ion-list、ion-item完成列表页ion-infinite-scroll上拉加载ion-refresher下拉刷新
  18. 循环彩灯c语言程序,PLC彩灯实例,一个简单的顺序控制
  19. this指向 改变this指向
  20. Hi3798CV200DMD_VER.B SCH原理图

热门文章

  1. python的django_真正搞明白Python中Django和Flask框架的区别
  2. 关于vs2010调用python中Py_Initialize函数报错的原因
  3. java app支付_Java 微信支付之APP支付服务端 (一)
  4. easymock参数_EasyMock参数匹配器
  5. kotlin_Kotlin
  6. kotlin数据类_Kotlin数据类
  7. mvc crud_Spring MVC Hibernate MySQL集成CRUD示例教程
  8. Java开发技术有哪些?
  9. C语言和C++的区别到底是什么?
  10. V8 7.4释出!支持JIT-less不需可执行内存也能执行