HTML 中的垂直文本 - 在网页中创建动态垂直文本图像
创建跨浏览器 HTML 垂直文本,

引言
此示例代码允许您使用自定义 HTTP Handler 和 .NET Graphics 库 - GDI+ 在 ASP.NET 网页中创建旋转的垂直文本图像。
背景
在最近的一个项目中,我被要求显示一个像上面这样的数据表,其中包含旋转的垂直文本列标题。对于可能有很多列的表格报告,垂直文本有时是用户查看数据的唯一方式。Internet Explorer 提供了一种使用 style="writing-mode:tb-rl"
显示垂直文本的方法,但其他浏览器都不支持,而我想要一个在 Firefox 和其他浏览器中都能工作的解决方案。
创建垂直文本图像
ImageCreationLibrary.cs 文件负责使用 Microsoft 的 .NET GDI+ 功能以我们想要的格式创建和保存垂直文本图像。
对我来说,最有效的策略是使用 StringFormatFlags.DirectionVertical
来绘制文本。棘手之处在于,它默认是从上到下书写文本,所以您需要将图像旋转 180 度并进行适当的平移。我认为大多数人更习惯于从下到上阅读垂直文本,因为每个单词的第一个字母将排在相同的位置。
ImageCreationLibrary.cs 中的主要代码位于 CreateVerticalTextImage
方法中。
public string CreateVerticalTextImage(string stText, Font f)
{
string stFileName = Toolbox.GetMD5String(stText);
string stFullFilePath = this._baseImagePath + stFileName + ".jpg";
if (!File.Exists(stFullFilePath))
{
StringFormat stringFormat = new StringFormat();
stringFormat.FormatFlags = StringFormatFlags.DirectionVertical;
SizeF imageSize = _graphics.MeasureString(stText, f, 25, stringFormat);
System.Drawing.Image i = (Image)new Bitmap((int)imageSize.Width,
(int)imageSize.Height);
Graphics g = Graphics.FromImage(i);
g.FillRectangle(Brushes.White, 0, 0, i.Width, i.Height);
//flip the image 180 degrees
g.TranslateTransform(i.Width, i.Height);
g.RotateTransform(180.0F);
g.DrawString(stText, f, Brushes.Black, 0, 0, stringFormat);
i.Save(stFullFilePath, System.Drawing.Imaging.ImageFormat.Jpeg);
}
return stFullFilePath;
}
CreateVerticalTextImage
根据传入的文本生成 MD5 哈希;您可以做其他事情,这只是一种确保文件路径中没有无效字符且名称相对唯一的方法。然后它创建一个足够大的白色框来容纳文本。使用 graphics 对象,我们调用 TranslateTransform
将图像平移回我们想要的位置,基于 180 度旋转。然后我们调用 RotateTransform
,传入 180 度来实际执行我们想要的旋转变换。最后,CreateVerticalTextImage
调用 graphics 对象上的 DrawString
来绘制我们的垂直文本,并保存图像。
Using the Code
嗯,这听起来都很不错,但我该如何使用这段代码将垂直文本图像实际包含在我的网页中呢?我已经创建了一个自定义的 HttpHandler
:ImageViewer.cs,ImageViewer
类继承自 IHttpHandler
,并在 ProcessRequest
方法中调用 CreateVerticalTextImage
,将我们称之为“text
”的 GET
参数传递给它。
//get the text passed in
string stText = context.Request.QueryString["text"];
if (stText != null && stText != "")
{
string stFileName = this.imageLib.CreateVerticalTextImage
(stText, new System.Drawing.Font(System.Drawing.FontFamily.GenericSerif, 12));
this.WriteImageFile(context, stFileName);
}
ImageViewer.cs 中的 WriteImageFile
方法只是根据图像文件扩展名设置内容类型,并调用我们 HttpContext
对象上的 Response.WriteFile(stFilePath)
。
确保在 Web.Config 文件中注册自定义 HttpHandler
,这样我们就可以确保对 get_image.aspx 的请求由 ImageViewer.cs 处理。
<system.web>
<httphandlers>
...
</httphandlers></system.web>
最后,要将我们的图像包含在网页中,我们需要 UrlEncode
我们想要在图像上显示的文本,并像这样将其作为查询字符串传递给 get_image.aspx。
string stGET = System.Web.HttpUtility.UrlEncode(stText);
string stImageTag = "<img src=\"get_image.aspx?text=" + stGET + "\"/>";
关注点
在处理 GDI+ 和矩阵变换时,您会从线性代数中学到(或记住)很多知识,在 Visual Studio 中使用 F1 键查找您正在使用的诸如 TranslateTransform
和 RotateTransform
等方法的文档和示例会很有帮助,并进行实验。有一点需要注意:根据文档,这些方法通过将指定的平移或旋转添加到变换矩阵的开头来工作,所以在我举例的场景中,实际上是先进行旋转,然后再进行平移。
参考文献
我在解决这个问题时得到了很多伟大参考文献的帮助(其中一些来自 CodeProject):非常感谢 Horia Tudosie 的 Vertical Labels in Web Pages 文章,这篇文章非常完善,帮助我弄清楚了一些用于正确渲染文本的 GDI+ 代码。我决定分享我的代码,是因为我想要一个从略微不同角度出发的简单示例,该示例还能保存创建的文件,这样图像只需要生成一次。我在 CodeProject 上找到的另一个很好的垂直文本 GDI+ 文章(VB)是 Vertical Label Control in VB.NET。
CSS 替代方案
最近,我偶然发现了一些 CSS 替代方案,它们可能不是在所有浏览器中都能正常工作,您可能需要对定位进行一些调整才能在所有浏览器中看起来一致,但我认为我应该更新这篇文章,加入一些关于我发现的信息。
Scott Gale 在 CSS Vertical Text 的帖子中,很好地解释了如何使用 Internet Explorer 的 writing-mode 以及 Mozilla 和 webkit 的 transform rotate 属性在 CSS 中创建旋转文本。然而,由于 Internet Explorer 的 writing-mode 不支持旋转 270 度(或 -90 度)的文本,您需要做一些更花哨(在我看来相当 hacky)的事情。Jonathan Snook 还有一篇关于 Text Rotation with CSS 的文章,使用 Internet Explorer 的 filter 属性可以实现 270 度垂直文本旋转。这是一个您可以应用到页面上进行尝试的完整 CSS 类。
.css-vertical-text {
-webkit-transform:rotate(270deg);
-moz-transform:rotate(270deg);
-o-transform: rotate(270deg);
white-space:nowrap;
display:block;
padding-left: 15px;
position:absolute;
right:-5px;
top:0px;
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
}
历史
- 2007/05/23 - 创建文章
- 2010/08/19 - 更新文章以包含 CSS 中的替代方案