GDI+简单现实文字旋转
原文 http://www.cnblogs.com/kaixiangbb/p/3301272.html
题记
入职新公司已快有两月了,试用期已快结束,项目却迟迟还未正式启动。安排给我的多是些琐事,一直未进入工作状态。公司也不在本地,我是属于公司在现场招 的,工作地点就在客户这边。刚来时还有其他几个到这边出差的同事,有专门过来带我熟悉业务的,但呆了一个月陆陆续续都回公司去了。现目前就我和另一个在这 边上学的研三的实习生同事,没有人管着又没多少事可做,着实闲得有点蛋疼。
一闲下来时间似乎就停滞了,博客园不知道刷新了多少次,可电脑右下角的时间距离下班还是那么长。浏览器关了又打开,重复了N多次,一遍一遍的F5多么期待 能够出现一篇耳目一新的博文,能够把我的游离灵魂带走,忘记那等待的煎熬。忙起来的时候,看的QQ群图标不停的在眼角余光中闪烁,不由得会烦躁起来,于是 立马屏蔽掉所有群消息。带上耳机静静地听着音乐,思考问题、敲打代码,一心只为写代码,两耳不闻窗外事。而这久,一看到群里有动静,不管啥话题,管它什么 人,都要去凑凑热闹,插个三言两语。特别是前不久博客园里争论.net与java的话题,我一看到这样的博文,会不由自主的把标题附带链接发到群里。结果 成为众矢之的,过街老鼠,人人喊打,都在骂我@#¥%……&*。看到群里顿时热闹起来,我到觉得骂我的不是事,反而有种优越感......。当 然,除了这些水话外,也经常有新手遇到问题时到群里提问的,大多都是些很入门级的基础知识,其实只要用好百度、msdn用点心都很容易解决问题的。止住, 啰哩啰嗦说了这么多水话,还是步入正题吧。
1、问题是这样的
在QQ群里有同学问GDI+如何实现文字旋转,实现的效果如下图:

看到这图还是有点意思的,因为自己没实现过,对GDI+也比较陌生又比较好奇。之前虽然接触过这方面的知识,但并不是很了解也仅限于皮毛。不过看到图的一 瞬间给我的感觉是也不难实现么,动下脑子思路已浮现出来。和这位同学大概说了下思路,具体的参考可以去百度上搜索,应该会有这方面的例子,.net基础的 知识在网上还是很容易搜到的。毕竟自己也是这样学习过来,一路成长起来,很多问题自己下点功夫、花点心思都能解决,没必要一碰到问题不经大脑思考就到处发 问。
第二天,这同学又在群里发问了,我很是纳闷难道网上找不到这方面的例子,真心有这么难么。于是和群里另一个朋友一起数落了下他,看看他是回答的如此心安理 得。我说:"你是不是学生,要多动脑筋",他答:"比学生还学生,不懂",朋友说:"基础不牢 一切都是浮云",他答:"没有基础"。最让我无语的是,因为自己闲着没事于是简单的做了个demo发给他,是用winform实现的。然后这位同学貌似很 急切的问我说:"你做的是winform平台,我做惯了网页平台,报了个错,看下",附带报错的截图。一看把小伙伴们都惊呆了,原来他直接把 form.cs里的main方法一块复制张贴,我这个心情,真不知道要如何回答他。
他那边能运行起来后,又开始发问了说:"怎么是固定的?不能生成一次变一次吗"、"asp.net中有没有随机旋转位置的函数,而不是这种有规律的"。我 做的简单,数字没随机生成,而是1、2、3...这样顺序的,并且旋转的角度是每次在上一次的基础上加上一个固定的旋转偏移量,然后就有了前面的问题。我 以为他不知道.net里的Random随机数对象,特地和他说了下,可以百度一下。结果他答:"嗯,这个是产生随机数,不过现在数字可以不变,我想让位置 随机,不知道有没有这样的函数,在此百度也是一样的"。我的小伙伴们我惊恐万分啊,真心只想来句,"草泥马戈壁,SB啊"。我承认我思想有点不纯洁,好在 忍了会又随口水一起咽回去了。
群里的那位朋友似乎也被惊呆了,按耐不住又开始数落这位同学,且看下精彩的对答吧,他问:"颜色是不是也可以随机啊?",我回:"动脑筋就可以",他 答:"基础差"。朋友回:"不是基础差,是不会举一反三",他答:"基础差,没信心,反三了怕不对",朋友很无奈狠狠的这样回了句:"你有一个JJ,你只会用它撒尿,不会用它日逼?"。我这双狗眼啊又再次被刺瞎了,然后群里纷纷接住这句话,不过都没文字,只发了个表情。看到这里,各位看官有何感想。这就是问题由来,下面就来解决问题吧。
2、实现
使用随机数对象来实现随机的数字、文字颜色、旋转角度就不多说了。下面是我的实现思路,首先看实现旋转的这个方法 public void RotateTransform(float angle),这个是Graphics对象的一个实例方法,参数为旋转的角度(以度为单位)。也就是说是现实对整个绘图图面(Graphics对象)的旋 转,而不是针对画板里的单个元素。那么就不能实现创建一个画板,然后分别把随机的数字旋转位置后再画到画板上。我的办法是先创建单个数字的小画板进行旋转 后用Graphics对象的DrawImage方法把它们画到大的画板上,即:把单个数字的小位图合并为大图。旋转的时候要注意一点,默认画板的原坐标点 是在左上角,此时如果以这个点为基准进行旋转后,会发现上面的数字跑到了别的地方,其实道理很简单,拿张纸试下就知道了呗。所以在旋转前,需要改变画板的 坐标原点为中点,使用的是Graphics对象的TranslateTransform(Single, Single)方法,描述:通过使此 Graphics 的变换矩阵左乘指定的平移来更改坐标系统的原点。源码如下:

/// <summary>
/// 生成单个小图
/// </summary>
/// <param name="s">数字</param>
/// <param name="c">数字颜色</param>
/// <param name="py">旋转偏移量</param>
/// <returns></returns>
public System.Drawing.Image BuildBitmap(string s, Color c,float py)
{
System.Drawing.Bitmap bitmap = new Bitmap(, );
var g = System.Drawing.Graphics.FromImage(bitmap);
g.Clear(Color.White);
//设置画板的坐标原点为中点
g.TranslateTransform(bitmap.Width/, bitmap.Height/);
//以指定角度对画板进行旋转
g.RotateTransform(py);
var size = g.MeasureString(s, new Font("arial", , FontStyle.Regular));
//让文字变得平滑
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
//把数字画到画板的中点位置
g.DrawString(s, new Font("arial", , FontStyle.Regular), new SolidBrush(c), (bitmap.Width - size.Width) / - bitmap.Width / , (bitmap.Height - size.Height) / - bitmap.Height / );
return bitmap;
} /// <summary>
/// 把小图合并为一个大图
/// </summary>
public void BuildBigImage()
{
Color[] c = new Color[] { Color.Red, Color.Green, Color.Maroon, Color.Blue, Color.BurlyWood, Color.Orange, Color.Lime, Color.MediumTurquoise, Color.Olive };
Bitmap bigImage = new Bitmap(, );//创建一个大位图
Graphics g=Graphics.FromImage(bigImage);//创建大图的画板
Random r = new Random(DateTime.Now.Millisecond);
var x = ;
var y = ;
for (int i = ; i < ; i++)
{
var color = c[r.Next(, )];
float py = r.Next(, ) * ;//长生随机的偏移量
var img = BuildBitmap(r.Next(, ).ToString(), color, py);
if (x == )
x = ;
if (i <= )
{
var point = new Point(x, y);//小图画到大图上的位置
g.DrawImage(img, point);//把小图画到大图上
}
else if (i > && i <= )
{
y = ;
var point = new Point(x, y);
g.DrawImage(img, point);//把小图画到大图上
}
else
{
y = ;
var point = new Point(x, y);
g.DrawImage(img, point);//把小图画到大图上
}
x = x + ;
}
//添加网格线
g.DrawLine(new Pen(new SolidBrush(Color.Gray), ), new Point(, ), new Point(, ));
g.DrawLine(new Pen(new SolidBrush(Color.Gray), ), new Point(, ), new Point(, ));
g.DrawLine(new Pen(new SolidBrush(Color.Gray), ), new Point(, ), new Point(, ));
g.DrawLine(new Pen(new SolidBrush(Color.Gray), ), new Point(, ), new Point(, ));
g.DrawLine(new Pen(new SolidBrush(Color.Gray), ), new Point(, ), new Point(, ));
g.DrawLine(new Pen(new SolidBrush(Color.Gray), ), new Point(, ), new Point(, ));
g.DrawLine(new Pen(new SolidBrush(Color.Gray), ), new Point(, ), new Point(, ));
g.DrawLine(new Pen(new SolidBrush(Color.Gray), ), new Point(, ), new Point(, ));
System.IO.MemoryStream sm = new System.IO.MemoryStream();
bigImage.Save(sm, System.Drawing.Imaging.ImageFormat.Png);
Response.ContentType = "image/png";
Response.BinaryWrite(sm.ToArray());
}

实现效果图如下:

以上就是实现文字旋转的所有过程,虽然没有原图那么漂亮,不过原理应当如此。
注册博客园已有一段时间了,但一直都是打酱油的角色,没写过几篇博文,如有不妥之处还望各位看官谅解给予指正,小弟在此谢过啦!
GDI+简单现实文字旋转的更多相关文章
- C# 使用 GDI+ 实现添加中心旋转(任意角度)的文字
这篇文章是 GDI+ 总结系列的第三篇,如果对 GDI+ 的基础使用不熟悉的朋友可以先看第一篇文章<C# 使用 GDI+ 画图>. 需求 需求是要实现给图片添加任意角度旋转的文字,文字的旋 ...
- 用Asp.net实现简单的文字水印
用Asp.net实现简单的文字水印 经常看见MOP上有人贴那种动态的图片,就是把一个字符串作为参数传给一个动态网页,就会生成一个带有这个字符串的图片,这个叫做文字水印.像什么原来的熊猫系列,还有后来 ...
- react球形文字旋转标签
/* * 球形文字旋转标签模块 * */ import React, {Component, PropTypes} from "react"; import ReactDOM fr ...
- C# 设置Word文本框中的文字旋转方向
在Word中可插入文本框,默认情况下插入的文本框中的文字方向为横向排列,对于一些特殊文档的设计要求,需要改变文字方向,如本次测试中的文档排版为考生试卷类型,考生信息栏的内容为下图中的这种, 本文将以C ...
- Java 设置Word文本框中的文字旋转方向
Word文档中可添加文本框,并设置文本框为横向文本排列或是纵向文本排列,或者设置文本框中的文字旋转方向等.通过Java程序代码,也可以实现以上文本框的操作.下面以Java代码示例展示具体的实现步骤.另 ...
- C# GDI+ 简单实现图片写文字和图片叠加(水印)(转)
using System; using System.Collections; using System.Configuration; using System.Data; using System. ...
- 【GDI+】 线段 文字 定位的问题
遇到一个看起来很简单的问题: 给定两个点,和一组文字,希望文字显示在线的附近并且居中显示.期望像这样的效果 进一步的抽象是: 1.根据文字的长度和高度,以及两个点,来获得文字的定位点(左上角点)的 2 ...
- C# (GDI+相关) 图像处理(各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果) (转)
C#图像处理 (各种旋转.改变大小.柔化.锐化.雾化.底片.浮雕.黑白.滤镜效果) 一.各种旋转.改变大小 注意:先要添加画图相关的using引用. //向右旋转图像90°代码如下 ...
- OpenGL绘制简单场景,实现旋转缩放平移和灯光效果
本项目实现了用OpenGL绘制一个简单场景,包括正方体.球体和网格,实现了物体的旋转.缩放.平移和灯光效果.附有项目完整代码.有具体凝视.适合刚開始学习的人熟悉opengl使用. 开发情况 开发环境V ...
随机推荐
- 安装windows7和ubuntu双系统后引导项设置
win7系统,U盘安装ubuntu,在选择[安装启动引导器的设备]时,1.如果你选择的是/dev/sda,即整个硬盘,他会将启动引导器使用grub进行系统引导,而不再使用windows loader, ...
- Linux下源码编译安装rpy2
R(又称R语言)是一款开源的跨平台的数值统计和数值图形化展现工具.rpy2是Python直接调用R的第三方库,它可以实现使用python读取R的对象.调用R的方法以及Python与R数据结构转换等.这 ...
- MVC WebApi 用户验证 (2)
构建ASP.NET MVC5+EF6+EasyUI 1.4.3+Unity4.x注入的后台管理系统(66)-MVC WebApi 用户验证 (2) 前言: 构建ASP.NET MVC5+EF6+E ...
- 山寨QQ音乐的布局(一)
学了两天IOS趁着还没忘光,巩固一下所学知识想做点东西,由于自己的设计能力有限,所以就山寨一下吧,说到山寨怎么能忘了腾讯呢,今天发现QQ音乐的设计风格是扁平化的,小清新风格,所以就山寨一下它吧.. 由 ...
- shell基础——字符串连接
#!/bin/sh str1="hello" str2="world" echo str1=$str1, str2=$str2 strconn1=$str1$s ...
- Qt4.7文档翻译:Qt样式单参考,Qt Style Sheets Reference(超长,超全)
内容目录 Qt样式单参考 可进行样式设置的部件列表 属性列表 图标列表 属性类型列表 伪状态列表 子控件列表 Qt样式单参考 Qt样式单支持各种属性.伪状态和子控件,这样使得妳能够自行设计部件的外观. ...
- linux命令之uname
uname是linux中查询系统基本信息的命令. 命令形式: uname [选项] 选项包括:(若不跟任何选项:则默认-s选项) -s, --kernel-name 输出内核名称 -n, --no ...
- sriov查看pf-vf对应关系
自己写的, 方便调试. $ cat pf-vf echo "physfn is $1"echo "pf info:"ls /sys/class/net/$1 - ...
- Z.Studio高级成衣定制(双井店)价格,地址(图)-北京-大众点评网
Z.Studio高级成衣定制(双井店)价格,地址(图)-北京-大众点评网 Z.Studio高级成衣定制(双井店)
- TreeView(C#)无限目录树代码片段
#region 绑定客户树 protected void bindTreeView() { TreeView1.Nodes.Clear(); string userid = Session[" ...