首页 > 代码库 > C#利用GDI+绘制旋转文字等效果

C#利用GDI+绘制旋转文字等效果

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

 

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

 

 

测试代码如下:

 

[csharp] view plaincopy在CODE上查看代码片派生到我的代码片
  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.   
  8. namespace RotateText  
  9. {  
  10.     public partial class FormMain : Form  
  11.     {  
  12.         private Font _font = new Font("Arial", 12);  
  13.         private Brush _brush = new SolidBrush(Color.Black);  
  14.         private Pen _pen = new Pen(Color.Black, 1f);  
  15.         private string _text = "Crow Soft";  
  16.   
  17.         public FormMain()  
  18.         {  
  19.             InitializeComponent();  
  20.         }  
  21.   
  22.         protected override void OnPaint(PaintEventArgs e)  
  23.         {  
  24.             base.OnPaint(e);  
  25.   
  26.             GraphicsText graphicsText = new GraphicsText();  
  27.             graphicsText.Graphics = e.Graphics;  
  28.   
  29.             // 绘制围绕点旋转的文本  
  30.             StringFormat format = new StringFormat();  
  31.             format.Alignment = StringAlignment.Center;  
  32.             format.LineAlignment = StringAlignment.Center;  
  33.   
  34.             graphicsText.DrawString(_text, _font, _brush, new PointF(100, 80), format, 45f);  
  35.             graphicsText.DrawString(_text, _font, _brush, new PointF(200, 80), format, -45f);  
  36.             graphicsText.DrawString(_text, _font, _brush, new PointF(300, 80), format, 90f);  
  37.             graphicsText.DrawString(_text, _font, _brush, new PointF(400, 80), format, -60f);  
  38.   
  39.             // 绘制矩形内旋转的文本  
  40.             // First line  
  41.             RectangleF rc = RectangleF.FromLTRB(50, 150, 200, 230);  
  42.             RectangleF rect = rc;  
  43.             format.Alignment = StringAlignment.Near;  
  44.   
  45.             e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);  
  46.             graphicsText.DrawString(_text, _font, _brush, rect, format, 30);  
  47.   
  48.             rect.Location += new SizeF(180, 0);  
  49.             format.LineAlignment = StringAlignment.Near;  
  50.             e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);  
  51.             graphicsText.DrawString(_text, _font, _brush, rect, format, -30);  
  52.   
  53.             rect.Location += new SizeF(180, 0);  
  54.             format.LineAlignment = StringAlignment.Center;  
  55.             e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);  
  56.             graphicsText.DrawString(_text, _font, _brush, rect, format, -90);  
  57.   
  58.             rect.Location += new SizeF(180, 0);  
  59.             format.LineAlignment = StringAlignment.Far;  
  60.             e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);  
  61.             graphicsText.DrawString(_text, _font, _brush, rect, format, 70);  
  62.   
  63.             // Second line  
  64.             rect = rc;  
  65.             rect.Location += new SizeF(0, 100);  
  66.             format.Alignment = StringAlignment.Center;  
  67.   
  68.             e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);  
  69.             graphicsText.DrawString(_text, _font, _brush, rect, format, 40);  
  70.   
  71.             rect.Location += new SizeF(180, 0);  
  72.             format.LineAlignment = StringAlignment.Near;  
  73.             e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);  
  74.             graphicsText.DrawString(_text, _font, _brush, rect, format, 30);  
  75.   
  76.             rect.Location += new SizeF(180, 0);  
  77.             format.LineAlignment = StringAlignment.Center;  
  78.             e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);  
  79.             graphicsText.DrawString(_text, _font, _brush, rect, format, -70);  
  80.   
  81.             rect.Location += new SizeF(180, 0);  
  82.             format.LineAlignment = StringAlignment.Far;  
  83.             e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);  
  84.             graphicsText.DrawString(_text, _font, _brush, rect, format, 60);  
  85.   
  86.             // Third line  
  87.             rect = rc;  
  88.             rect.Location += new SizeF(0, 200);  
  89.             format.Alignment = StringAlignment.Far;  
  90.   
  91.             e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);  
  92.             graphicsText.DrawString(_text, _font, _brush, rect, format, -30);  
  93.   
  94.             rect.Location += new SizeF(180, 0);  
  95.             format.LineAlignment = StringAlignment.Near;  
  96.             e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);  
  97.             graphicsText.DrawString(_text, _font, _brush, rect, format, -30);  
  98.   
  99.             rect.Location += new SizeF(180, 0);  
  100.             format.LineAlignment = StringAlignment.Center;  
  101.             e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);  
  102.             graphicsText.DrawString(_text, _font, _brush, rect, format, 90);  
  103.   
  104.             rect.Location += new SizeF(180, 0);  
  105.             format.LineAlignment = StringAlignment.Far;  
  106.             e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);  
  107.             graphicsText.DrawString(_text, _font, _brush, rect, format, 45);  
  108.         }  
  109.     }  
  110. }  

 

 

效果如下图:

 

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

C#利用GDI+绘制旋转文字等效果