65.9K
CodeProject 正在变化。 阅读更多。
Home

HTML 中的垂直文本 - 在网页中创建动态垂直文本图像

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (12投票s)

2007年5月23日

CPOL

4分钟阅读

viewsIcon

123535

downloadIcon

800

创建跨浏览器 HTML 垂直文本,而无需使用 Internet Explorer 特定的布局流或书写模式。

Screenshot - vertical_text-firefox_ss.jpg

引言

此示例代码允许您使用自定义 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

嗯,这听起来都很不错,但我该如何使用这段代码将垂直文本图像实际包含在我的网页中呢?我已经创建了一个自定义的 HttpHandlerImageViewer.csImageViewer 类继承自 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 中的替代方案
© . All rights reserved.