C#中利用GDI+绘制旋转文本的文字,网上有很多资料,基本都使用矩阵旋转的方式实现。但基本都只提及按点旋转,若要实现在矩形范围内旋转文本,资料较少。经过琢磨,可以将矩形内旋转转化为按点旋转,不过需要经过不少的计算过程。利用下面的类可以实现该功能。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Drawing.Drawing2D;
  5. namespace RotateText
  6. {
  7. public class GraphicsText
  8. {
  9. private Graphics _graphics;
  10. public GraphicsText()
  11. {
  12. }
  13. public Graphics Graphics
  14. {
  15. get { return _graphics; }
  16. set { _graphics = value; }
  17. }
  18. /// <summary>
  19. /// 绘制根据矩形旋转文本
  20. /// </summary>
  21. /// <param name="s">文本</param>
  22. /// <param name="font">字体</param>
  23. /// <param name="brush">填充</param>
  24. /// <param name="layoutRectangle">局部矩形</param>
  25. /// <param name="format">布局方式</param>
  26. /// <param name="angle">角度</param>
  27. public void DrawString(string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format, float angle)
  28. {
  29. // 求取字符串大小
  30. SizeF size = _graphics.MeasureString(s, font);
  31. // 根据旋转角度,求取旋转后字符串大小
  32. SizeF sizeRotate = ConvertSize(size, angle);
  33. // 根据旋转后尺寸、布局矩形、布局方式计算文本旋转点
  34. PointF rotatePt = GetRotatePoint(sizeRotate, layoutRectangle, format);
  35. // 重设布局方式都为Center
  36. StringFormat newFormat = new StringFormat(format);
  37. newFormat.Alignment = StringAlignment.Center;
  38. newFormat.LineAlignment = StringAlignment.Center;
  39. // 绘制旋转后文本
  40. DrawString(s, font, brush, rotatePt, newFormat, angle);
  41. }
  42. /// <summary>
  43. /// 绘制根据点旋转文本,一般旋转点给定位文本包围盒中心点
  44. /// </summary>
  45. /// <param name="s">文本</param>
  46. /// <param name="font">字体</param>
  47. /// <param name="brush">填充</param>
  48. /// <param name="point">旋转点</param>
  49. /// <param name="format">布局方式</param>
  50. /// <param name="angle">角度</param>
  51. public void DrawString(string s, Font font, Brush brush, PointF point, StringFormat format, float angle)
  52. {
  53. // Save the matrix
  54. Matrix mtxSave = _graphics.Transform;
  55. Matrix mtxRotate = _graphics.Transform;
  56. mtxRotate.RotateAt(angle, point);
  57. _graphics.Transform = mtxRotate;
  58. _graphics.DrawString(s, font, brush, point, format);
  59. // Reset the matrix
  60. _graphics.Transform = mtxSave;
  61. }
  62. private SizeF ConvertSize(SizeF size, float angle)
  63. {
  64. Matrix matrix = new Matrix();
  65. matrix.Rotate(angle);
  66. // 旋转矩形四个顶点
  67. PointF[] pts = new PointF[4];
  68. pts[0].X = -size.Width / 2f;
  69. pts[0].Y = -size.Height / 2f;
  70. pts[1].X = -size.Width / 2f;
  71. pts[1].Y = size.Height / 2f;
  72. pts[2].X = size.Width / 2f;
  73. pts[2].Y = size.Height / 2f;
  74. pts[3].X = size.Width / 2f;
  75. pts[3].Y = -size.Height / 2f;
  76. matrix.TransformPoints(pts);
  77. // 求取四个顶点的包围盒
  78. float left = float.MaxValue;
  79. float right = float.MinValue;
  80. float top = float.MaxValue;
  81. float bottom = float.MinValue;
  82. foreach(PointF pt in pts)
  83. {
  84. // 求取并集
  85. if(pt.X < left)
  86. left = pt.X;
  87. if(pt.X > right)
  88. right = pt.X;
  89. if(pt.Y < top)
  90. top = pt.Y;
  91. if(pt.Y > bottom)
  92. bottom = pt.Y;
  93. }
  94. SizeF result = new SizeF(right - left, bottom - top);
  95. return result;
  96. }
  97. private PointF GetRotatePoint(SizeF size, RectangleF layoutRectangle, StringFormat format)
  98. {
  99. PointF pt = new PointF();
  100. switch (format.Alignment)
  101. {
  102. case StringAlignment.Near:
  103. pt.X = layoutRectangle.Left + size.Width / 2f;
  104. break;
  105. case StringAlignment.Center:
  106. pt.X = (layoutRectangle.Left + layoutRectangle.Right) / 2f;
  107. break;
  108. case StringAlignment.Far:
  109. pt.X = layoutRectangle.Right - size.Width / 2f;
  110. break;
  111. default:
  112. break;
  113. }
  114. switch (format.LineAlignment)
  115. {
  116. case StringAlignment.Near:
  117. pt.Y = layoutRectangle.Top + size.Height / 2f;
  118. break;
  119. case StringAlignment.Center:
  120. pt.Y = (layoutRectangle.Top + layoutRectangle.Bottom) / 2f;
  121. break;
  122. case StringAlignment.Far:
  123. pt.Y = layoutRectangle.Bottom - size.Height / 2f;
  124. break;
  125. default:
  126. break;
  127. }
  128. return pt;
  129. }
  130. }
  131. }

测试代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Windows.Forms;
  7. namespace RotateText
  8. {
  9. public partial class FormMain : Form
  10. {
  11. private Font _font = new Font("Arial", 12);
  12. private Brush _brush = new SolidBrush(Color.Black);
  13. private Pen _pen = new Pen(Color.Black, 1f);
  14. private string _text = "Crow Soft";
  15. public FormMain()
  16. {
  17. InitializeComponent();
  18. }
  19. protected override void OnPaint(PaintEventArgs e)
  20. {
  21. base.OnPaint(e);
  22. GraphicsText graphicsText = new GraphicsText();
  23. graphicsText.Graphics = e.Graphics;
  24. // 绘制围绕点旋转的文本
  25. StringFormat format = new StringFormat();
  26. format.Alignment = StringAlignment.Center;
  27. format.LineAlignment = StringAlignment.Center;
  28. graphicsText.DrawString(_text, _font, _brush, new PointF(100, 80), format, 45f);
  29. graphicsText.DrawString(_text, _font, _brush, new PointF(200, 80), format, -45f);
  30. graphicsText.DrawString(_text, _font, _brush, new PointF(300, 80), format, 90f);
  31. graphicsText.DrawString(_text, _font, _brush, new PointF(400, 80), format, -60f);
  32. // 绘制矩形内旋转的文本
  33. // First line
  34. RectangleF rc = RectangleF.FromLTRB(50, 150, 200, 230);
  35. RectangleF rect = rc;
  36. format.Alignment = StringAlignment.Near;
  37. e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
  38. graphicsText.DrawString(_text, _font, _brush, rect, format, 30);
  39. rect.Location += new SizeF(180, 0);
  40. format.LineAlignment = StringAlignment.Near;
  41. e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
  42. graphicsText.DrawString(_text, _font, _brush, rect, format, -30);
  43. rect.Location += new SizeF(180, 0);
  44. format.LineAlignment = StringAlignment.Center;
  45. e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
  46. graphicsText.DrawString(_text, _font, _brush, rect, format, -90);
  47. rect.Location += new SizeF(180, 0);
  48. format.LineAlignment = StringAlignment.Far;
  49. e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
  50. graphicsText.DrawString(_text, _font, _brush, rect, format, 70);
  51. // Second line
  52. rect = rc;
  53. rect.Location += new SizeF(0, 100);
  54. format.Alignment = StringAlignment.Center;
  55. e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
  56. graphicsText.DrawString(_text, _font, _brush, rect, format, 40);
  57. rect.Location += new SizeF(180, 0);
  58. format.LineAlignment = StringAlignment.Near;
  59. e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
  60. graphicsText.DrawString(_text, _font, _brush, rect, format, 30);
  61. rect.Location += new SizeF(180, 0);
  62. format.LineAlignment = StringAlignment.Center;
  63. e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
  64. graphicsText.DrawString(_text, _font, _brush, rect, format, -70);
  65. rect.Location += new SizeF(180, 0);
  66. format.LineAlignment = StringAlignment.Far;
  67. e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
  68. graphicsText.DrawString(_text, _font, _brush, rect, format, 60);
  69. // Third line
  70. rect = rc;
  71. rect.Location += new SizeF(0, 200);
  72. format.Alignment = StringAlignment.Far;
  73. e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
  74. graphicsText.DrawString(_text, _font, _brush, rect, format, -30);
  75. rect.Location += new SizeF(180, 0);
  76. format.LineAlignment = StringAlignment.Near;
  77. e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
  78. graphicsText.DrawString(_text, _font, _brush, rect, format, -30);
  79. rect.Location += new SizeF(180, 0);
  80. format.LineAlignment = StringAlignment.Center;
  81. e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
  82. graphicsText.DrawString(_text, _font, _brush, rect, format, 90);
  83. rect.Location += new SizeF(180, 0);
  84. format.LineAlignment = StringAlignment.Far;
  85. e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
  86. graphicsText.DrawString(_text, _font, _brush, rect, format, 45);
  87. }
  88. }
  89. }

效果如下图:

资源地址:http://download.csdn.net/detail/alicehyxx/6626473

C#利用GDI+绘制旋转文字等效果的更多相关文章

  1. 测试canvas绘制旋转文字的性能

    canvas 绘制各种动画效果时,我们经常会使用画布旋转,使绘制上去的元素有旋转的效果. 最近在项目中碰到了很严重的性能问题,经常排查发现是因为绘制批量文字时使用了画布旋转,且每行文字的旋转角度是不一 ...

  2. CSS环绕球体的旋转文字-3D效果

    代码地址如下:http://www.demodashi.com/demo/12482.html 项目文件结构截图 只需要一个html文件既可: 项目截图: 代码实现原理: 该示例的实现过程很简单,主要 ...

  3. 自定义控件使用GDI+绘制旋转Label文字

    http://www.cnblogs.com/CUIT-DX037/ 1.添加用户控件: 2.添加代码: public partial class UcLabel : UserControl { pu ...

  4. GDI+简单现实文字旋转

    原文 http://www.cnblogs.com/kaixiangbb/p/3301272.html 题记 入职新公司已快有两月了,试用期已快结束,项目却迟迟还未正式启动.安排给我的多是些琐事,一直 ...

  5. GDI绘制时钟效果,与系统时间保持同步,基于Winform

    2018年工作之余,想起来捡起GDI方面的技术,特意在RichCodeBox项目中做了两个示例程序,其中一个就是时钟效果,纯C#开发.这个CSharpQuartz是今天上午抽出一些时间,编写的,算是偷 ...

  6. Winform GDI+绘图二:绘制旋转太极图

    大家好,今天有时间给大家带来Winform自绘控件的第二部分,也是比较有意思的一个控件:旋转太极图. 大家可以停下思考一下,如果让你来绘制旋转的太极图,大家有什么样的思路呢?我今天跟大家展示一下,我平 ...

  7. 学习笔记:利用GDI+生成简单的验证码图片

    学习笔记:利用GDI+生成简单的验证码图片 /// <summary> /// 单击图片时切换图片 /// </summary> /// <param name=&quo ...

  8. CSS3绘制旋转的太极图案(一)

        实现步骤: 基础HTML: <div class="box-taiji"> <div class="circle-01">< ...

  9. 利用QPainter绘制各种图形(Shape, Pen 宽带,颜色,风格,Cap,Join,刷子)

    利用QPainter绘制各种图形 Qt的二维图形引擎是基于QPainter类的.QPainter既可以绘制几何形状(点.线.矩形.椭圆.弧形.弦形.饼状图.多边形和贝塞尔曲线),也可以绘制像素映射.图 ...

随机推荐

  1. memcache、memcached、groupcache的区别

    对PHP语言来说,PHP使用memcache有两个模块,分别叫memcache和memcached,他们的区别看下表: 参考:http://hi.baidu.com/tony_wd/item/605e ...

  2. Python 读取excel

    一.到python官网下载http://pypi.python.org/pypi/xlrd模块安装, sudo python setup.py install 二.使用介绍 1.导入模块 import ...

  3. 数往知来 ASP.NET_多线程_Socket<十五>

    一.ASP.NET B/S  做网站(动态).管理系统(OA,进销存等) C/S--窗体软件 为什么现在很少用C/S做进销存等软件 B/S部署方便   C/S要安装 动态:与服务器(IIS(软件))进 ...

  4. 朝鲜RedStar_OS_3.0安装图解

    前天exploit-db上出现了3个Local Exploit,都是来自朝鲜的RedStar 3.0的vul.网上也下到了镜像,按网上的方法测试了下,真的是 ————————————————————— ...

  5. Cocos2d-JS v3.0 alpha不支持cocos2d-x的Physics integration

    cocos2d-x 3.0新的Physics integration,把chipmunk和Box2D封装到引擎内部 auto scene = Scene::createWithPhysics(); s ...

  6. 轻松学习Linux之入门篇

    1.Linux概述: 2.Linux优点 3.linux历史待上传 4.linux部分发行版 5.linux政府扶持 本文出自 "李晨光原创技术博客" 博客,谢绝转载!

  7. 通过Microsoft Azure服务设计网络架构的经验分享(转)

    原文:http://www.infoq.com/cn/articles/azure-networking-tips 本文从产品设计和架构角度分享了 Microsoft Azure 网络服务方面的使用经 ...

  8. UTC+0800是什么意思

    <%@ language="javascript" %> <html> <body> <% var d=new Date() var h= ...

  9. Light oj 1100 - Again Array Queries (鸽巢原理+暴力)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1100 给你n个数,数的范围是1~1000,给你q个询问,每个询问问你l到r之间 ...

  10. JavaServer Faces 2.2 requires Dynamic Web Module 2.5 or newer

    Description Resource Path Location Type JavaServer Faces 2.2 can not be installed : One or more cons ...