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

本文实例讲述了C#利用GDI+绘制旋转文字等效果的方法,是非常实用的技巧。分享给大家供大家参考之用。具体如下:

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

具体实现代码如下:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace RotateText
{
  public class GraphicsText
  {
    private Graphics _graphics;
    public GraphicsText()
    { 

    }
    public Graphics Graphics
    {
      get { return _graphics; }
      set { _graphics = value; }
    }
    /// <summary>
    /// 绘制根据矩形旋转文本
    /// </summary>
    /// <param name="s">文本</param>
    /// <param name="font">字体</param>
    /// <param name="brush">填充</param>
    /// <param name="layoutRectangle">局部矩形</param>
    /// <param name="format">布局方式</param>
    /// <param name="angle">角度</param>
    public void DrawString(string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format, float angle)
    {
      // 求取字符串大小
      SizeF size = _graphics.MeasureString(s, font); 

      // 根据旋转角度,求取旋转后字符串大小
      SizeF sizeRotate = ConvertSize(size, angle); 

      // 根据旋转后尺寸、布局矩形、布局方式计算文本旋转点
      PointF rotatePt = GetRotatePoint(sizeRotate, layoutRectangle, format); 

      // 重设布局方式都为Center
      StringFormat newFormat = new StringFormat(format);
      newFormat.Alignment = StringAlignment.Center;
      newFormat.LineAlignment = StringAlignment.Center; 

      // 绘制旋转后文本
      DrawString(s, font, brush, rotatePt, newFormat, angle);
    }
    /// <summary>
    /// 绘制根据点旋转文本,一般旋转点给定位文本包围盒中心点
    /// </summary>
    /// <param name="s">文本</param>
    /// <param name="font">字体</param>
    /// <param name="brush">填充</param>
    /// <param name="point">旋转点</param>
    /// <param name="format">布局方式</param>
    /// <param name="angle">角度</param>
    public void DrawString(string s, Font font, Brush brush, PointF point, StringFormat format, float angle)
    {
      // Save the matrix
      Matrix mtxSave = _graphics.Transform; 

      Matrix mtxRotate = _graphics.Transform;
      mtxRotate.RotateAt(angle, point);
      _graphics.Transform = mtxRotate; 

      _graphics.DrawString(s, font, brush, point, format); 

      // Reset the matrix
      _graphics.Transform = mtxSave;
    }
    private SizeF ConvertSize(SizeF size, float angle)
    {
      Matrix matrix = new Matrix();
      matrix.Rotate(angle);
      // 旋转矩形四个顶点
      PointF[] pts = new PointF[4];
      pts[0].X = -size.Width / 2f;
      pts[0].Y = -size.Height / 2f;
      pts[1].X = -size.Width / 2f;
      pts[1].Y = size.Height / 2f;
      pts[2].X = size.Width / 2f;
      pts[2].Y = size.Height / 2f;
      pts[3].X = size.Width / 2f;
      pts[3].Y = -size.Height / 2f;
      matrix.TransformPoints(pts);
      // 求取四个顶点的包围盒
      float left = float.MaxValue;
      float right = float.MinValue;
      float top = float.MaxValue;
      float bottom = float.MinValue;
      foreach(PointF pt in pts)
      {
        // 求取并集
        if(pt.X < left)
          left = pt.X;
        if(pt.X > right)
          right = pt.X;
        if(pt.Y < top)
          top = pt.Y;
        if(pt.Y > bottom)
          bottom = pt.Y;
      }
      SizeF result = new SizeF(right - left, bottom - top);
      return result;
    }
    private PointF GetRotatePoint(SizeF size, RectangleF layoutRectangle, StringFormat format)
    {
      PointF pt = new PointF(); 

      switch (format.Alignment)
      {
        case StringAlignment.Near:
          pt.X = layoutRectangle.Left + size.Width / 2f;
          break;
        case StringAlignment.Center:
          pt.X = (layoutRectangle.Left + layoutRectangle.Right) / 2f;
          break;
        case StringAlignment.Far:
          pt.X = layoutRectangle.Right - size.Width / 2f;
          break;
        default:
          break;
      }
      switch (format.LineAlignment)
      {
        case StringAlignment.Near:
          pt.Y = layoutRectangle.Top + size.Height / 2f;
          break;
        case StringAlignment.Center:
          pt.Y = (layoutRectangle.Top + layoutRectangle.Bottom) / 2f;
          break;
        case StringAlignment.Far:
          pt.Y = layoutRectangle.Bottom - size.Height / 2f;
          break;
        default:
          break;
      }
      return pt;
    }
  }
}

测试代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms; 

namespace RotateText
{
  public partial class FormMain : Form
  {
    private Font _font = new Font("Arial", 12);
    private Brush _brush = new SolidBrush(Color.Black);
    private Pen _pen = new Pen(Color.Black, 1f);
    private string _text = "Crow Soft"; 

    public FormMain()
    {
      InitializeComponent();
    } 

    protected override void OnPaint(PaintEventArgs e)
    {
      base.OnPaint(e); 

      GraphicsText graphicsText = new GraphicsText();
      graphicsText.Graphics = e.Graphics; 

      // 绘制围绕点旋转的文本
      StringFormat format = new StringFormat();
      format.Alignment = StringAlignment.Center;
      format.LineAlignment = StringAlignment.Center; 

      graphicsText.DrawString(_text, _font, _brush, new PointF(100, 80), format, 45f);
      graphicsText.DrawString(_text, _font, _brush, new PointF(200, 80), format, -45f);
      graphicsText.DrawString(_text, _font, _brush, new PointF(300, 80), format, 90f);
      graphicsText.DrawString(_text, _font, _brush, new PointF(400, 80), format, -60f); 

      // 绘制矩形内旋转的文本
      // First line
      RectangleF rc = RectangleF.FromLTRB(50, 150, 200, 230);
      RectangleF rect = rc;
      format.Alignment = StringAlignment.Near; 

      e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
      graphicsText.DrawString(_text, _font, _brush, rect, format, 30); 

      rect.Location += new SizeF(180, 0);
      format.LineAlignment = StringAlignment.Near;
      e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
      graphicsText.DrawString(_text, _font, _brush, rect, format, -30); 

      rect.Location += new SizeF(180, 0);
      format.LineAlignment = StringAlignment.Center;
      e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
      graphicsText.DrawString(_text, _font, _brush, rect, format, -90); 

      rect.Location += new SizeF(180, 0);
      format.LineAlignment = StringAlignment.Far;
      e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
      graphicsText.DrawString(_text, _font, _brush, rect, format, 70); 

      // Second line
      rect = rc;
      rect.Location += new SizeF(0, 100);
      format.Alignment = StringAlignment.Center; 

      e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
      graphicsText.DrawString(_text, _font, _brush, rect, format, 40); 

      rect.Location += new SizeF(180, 0);
      format.LineAlignment = StringAlignment.Near;
      e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
      graphicsText.DrawString(_text, _font, _brush, rect, format, 30); 

      rect.Location += new SizeF(180, 0);
      format.LineAlignment = StringAlignment.Center;
      e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
      graphicsText.DrawString(_text, _font, _brush, rect, format, -70); 

      rect.Location += new SizeF(180, 0);
      format.LineAlignment = StringAlignment.Far;
      e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
      graphicsText.DrawString(_text, _font, _brush, rect, format, 60); 

      // Third line
      rect = rc;
      rect.Location += new SizeF(0, 200);
      format.Alignment = StringAlignment.Far; 

      e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
      graphicsText.DrawString(_text, _font, _brush, rect, format, -30); 

      rect.Location += new SizeF(180, 0);
      format.LineAlignment = StringAlignment.Near;
      e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
      graphicsText.DrawString(_text, _font, _brush, rect, format, -30); 

      rect.Location += new SizeF(180, 0);
      format.LineAlignment = StringAlignment.Center;
      e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
      graphicsText.DrawString(_text, _font, _brush, rect, format, 90); 

      rect.Location += new SizeF(180, 0);
      format.LineAlignment = StringAlignment.Far;
      e.Graphics.DrawRectangle(_pen, rect.Left, rect.Top, rect.Width, rect.Height);
      graphicsText.DrawString(_text, _font, _brush, rect, format, 45);
    }
  }
}

效果如下图:

完整实例点此本站下载。

希望本文所述对大家的C#程序设计有所帮助

(0)

相关推荐

  • C#实现winform渐变效果的方法

    本文实例实现一个启动画面,采用了显示Aform,过一段时间,隐藏这个Aform,showdialog下一个Bform,closeAForm这个方法来做了,不知道大家有没有更好的办法. 设定程序从Aform启动: 复制代码 代码如下: static void Main()  {    Application.EnableVisualStyles();    Application.SetCompatibleTextRenderingDefault(false);    Application.Ru

  • C# WinForm实现Win7 Aero透明效果代码

    在Vista系统之后,微软为窗体程序提供了Aero磨砂的效果,如下图.那么用C#如何来实现这种磨砂效果呢? 背景为我的桌面 那先上代码吧: [StructLayout(LayoutKind.Sequential)] public struct MARGINS { public int Left; public int Right; public int Top; public int Bottom; } [DllImport("dwmapi.dll", PreserveSig = fa

  • C#实现窗体淡入淡出效果的方法总结

    1. 复制代码 代码如下: private   void   Form1_Load(object   sender,   System.EventArgs   e)     for(double   d=0.01;   d<   1;   d+=0.02)     {     System.Threading.Thread.Sleep(1);     Application.DoEvents();     this.Opacity=d;     this.Refresh();     } 2.

  • C#实现漂亮的数字时钟效果

    本文实例讲述了用C#做了一个漂亮的数字时钟.分享给大家供大家参考. 程序运行后界面如下: 实现技术:主要是通过Graphics类的DrawImage方法来绘制数字时钟中所有的数字,这些数字是从网上找的一些图片文件.时钟使用DateTime中Now属性来获得不同的,时,分,秒,最后通过定时器来实现时钟的运行状态. 主要代码如下: 复制代码 代码如下: //将0~9数字图片保存在Image数组中  private Image[] image = new Bitmap[10];  public For

  • C# 无边框窗体边框阴影效果的简单实现

    通过下面代码在构造函数中调用方法 SetShadow(); 即可实现无边框窗体的阴影效果了 需要添加命名空间 using System.Runtime.InteropServices; 复制代码 代码如下: private const int CS_DropSHADOW = 0x20000;        private const int GCL_STYLE = (-26); [DllImport("user32.dll", CharSet = CharSet.Auto)]     

  • C#图像处理之木刻效果实现方法

    本文实例讲述了C#图像处理之木刻效果实现方法.分享给大家供大家参考.具体如下: //木刻效果 public Bitmap PFilterMuKe(Bitmap src) { try { Bitmap a = new Bitmap(src); Rectangle rect = new Rectangle(0, 0, a.Width, a.Height); System.Drawing.Imaging.BitmapData bmpData = a.LockBits(rect, System.Draw

  • C#实现绘制浮雕图片效果实例

    本文采用C#实例讲解了处理图片为浮雕效果的实现方法,这在PS中是一个常见的功能,也是C#中的一个简单的图像处理例子.程序先读取原图,然后依次访问每个像素的RGB值,获取相邻两个像素的R.G.B值,计算与左上角像素的RGB分量之差,将计算后的RGB值回写到位图,最后进行图片的浮雕处理. 主要代码如下: using System; using System.Drawing; using System.Collections; using System.ComponentModel; using Sy

  • C#图像处理之浮雕效果实现方法

    本文实例讲述了C#图像处理之浮雕效果实现方法.分享给大家供大家参考.具体如下: //定义浮雕处理函数 public Bitmap PFudiao(Bitmap a) { try { int w = a.Width; int h = a.Height; Bitmap dstBitmap = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format24bppRgb); System.Drawing.Imaging.BitmapData sr

  • C#图像处理之霓虹效果实现方法

    本文实例讲述了C#图像处理之霓虹效果实现方法.分享给大家供大家参考.具体如下: //定义霓虹处理函数 public Bitmap PNihong(Bitmap a) { try { int w = a.Width; int h = a.Height; Bitmap dstBitmap = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format24bppRgb); System.Drawing.Imaging.BitmapData sr

  • C#实现3D效果完整实例

    本文实例讲述了C#实现3D效果的方法.分享给大家供大家参考,具体如下: 一.新建一类文件 private static double[] addVector(double[] a, double[] b) { return new double[] { a[0] + b[0], a[1] + b[1], a[2] + b[2] }; } private static double[] scalarProduct(double[] vector, double scalar) { return n

  • C#实现闪动托盘图标效果的方法

    本文实例讲述了C#实现闪动托盘图标效果的方法.分享给大家供大家参考,具体如下: 在用户正在登录QQ或者使用Firemail邮件系统自动收取邮件的时候,托盘图标会闪动提示用户正在运行的任务. 闪动图标可以使用定时切换托盘图标的方式实现,托盘图标可以从ImageList控件中获取.在ImageList控件里面添加三个icon,第一个icon表示窗体启动以后的托盘图标.第二个和第三个图标分别表示当特定的任务发生的时候,定时切换的图标. (1)设置托盘的图标可以从ImageList控件中的Image对象

  • C#自动生成漂亮的水晶效果头像的实现代码

    与其他的微博系统相同,在"多可内网微博系统"的用户也可上传自己的头像,并支持头像裁剪. 但"多可内网微博系统"的头像可以更漂亮,因为系统实现了水晶效果的头像.C#程序实现水晶效果头像的过程是: (1)图像缩略到宽度或高度=90的头像: (2)由用户选择合适的位置裁剪90x90的最终头像: (3)添加水晶效果: 代码奉献: 复制代码 代码如下: /// <summary>/// 绘制水晶效果的头像/// </summary>/// <pa

随机推荐