在网页中,垂直标签

分享于 

17分钟阅读

Web开发

  繁體

Sample Image - hello colorful world!

介绍

最近一个项目必须在 table的header 中显示长标签。 虽然列的内容保持较小,但 header 却在增长。 完成这个任务的最好方法是使用 900个旋转文本。 但是,我不知道在HTML中旋转文本的任何技巧。 以下是另一个管理器的概念,用于在页面上创建位图并在页面中绘制一个垂直标签。

在开发这个项目时,我遇到了许多文章,这些文章涉及到如何。 然而,很多小细节出现在方法中,我觉得在文章中对它们进行汇总是有益的。

前提条件

我唯一的选择就是- - 构建小位图并使用它们 <src=。> 标记。然后创建一个用于简化创建页面的任务的web服务。 WebControl会有另外的好处: 它可以绑定 Text 属性,以便页面动态创建标签或者对它的进行本地化。

但是,我不希望将所有生成的映像存储在硬盘上的文件中: 每个文件都有独特的NAME,除了生成( 长) 名称之外,文件很快会在服务器上积累。 幸运的是 IMG SRC 标签属性接受URL作为文件 NAME,这里URL也可以是返回一个与 gif/jpg文件位图相同的program/script/page的URL。

因此,任务分为两个较小的任务:

  • 创建一个生成器页,用于 SRC 属性
  • 把所有的东西都打包。

VerticalText页面

让我们开始编写 VerticalText.aspx 页面:

namespace WebImageTest {
 ///<summary>/// VerticalText is a peculiar page which returns/// an image instead of an HTML code.///</summary>publicclass VerticalText : System.Web.UI.Page {
 privatevoid Page_Load(object sender, System.EventArgs e) {//... Response.ContentType = "image/png";
 Response.BinaryWrite( ms.ToArray() );//... }//... }
}

这个ASPX在它的内容的意义上是特殊的: 而不是返回HTML内容( <标头> , <正文> 等等 ),它返回一个图片。 这是在 Page_Load 方法中实现的,行如下:

Response.ContentType = "image/png";

ContentType,使用默认的"text/HTML" 可以更改响应,并产生有趣的结果。 例如可以同样的方式在客户端机器上启动 Excel,使用内容,可以直接启动 Paintbrush 或者使用 "image/gif" - PhotoPaint (。假定相应的文件扩展名关联)。

上面 代码生成 PNG ( 可移植网络图形) 内容。

在键入以下地址时,我们将目标 http://localhost/WebImageTest/VerticalText.aspx?Text=Hello%20World&Font=Arial|24|B 浏览器将呈现以下图像:

Direct call to VerticalText.aspx page

在这里值得注意的是,我必须选择所有其他可用格式的PNG格式。 首先,用 GIF,我可以使用以下( 短/少) 行:

Response.ContentType = "image/gif";
bm.Save(Response.OutputStream, ImageFormat.Gif);

然而,这种方法生成的输出通过使用 256种颜色的调色板来实现光栅。 在 OutputStream 工作中保存以及JPEG格式,但由于不可以控压缩率,JPEG图像有点脏。 另一方面,PNG格式在屏幕上看起来很好,但不能保存在 OutputStream 中( 尽管没有提示创建 MemoryStream的方法)。

PNG image magnified 3 timesGif image magnified 3 timesJpg image magnified 3 times

给我们一些参数

当然,我们需要标签文本的参数。 那么很重要的是能够指定字体,除非我们想要遵守默认值。 然后,我们可以通过更改 background 颜色和文本的墨迹来扩展一点思想。 lithe的padding 在某些情况下是有益的。

默认值很好:当用户忘记或者不需要给出值时,对象应该能够呈现某些事物而不是给x 框。 Page_Load 从请求URL中获取这些值。 按照设计,URL应该如下所示:

VerticalText.aspx?Text=Hello World&Font=
 Arial|24|B&BgColor=DarkGoldenrod&FrColor=Orange&Padding=3

众所周知,在页面名称名称之后,使用 ? 引入参数,并用 & 分隔。 为了简化和减少线条的长度,我使用 | 分隔符压缩字体参数,并将命令作为: <Font name>|<Font Size>|<Font attributes> 实际上,代码:

string fontName = "Arial";int fontSize = 12;
FontStyle fontStyle = new FontStyle();try {
 string [] fontStr =
 Request["Font"].Split(new char[] {'|',',',' ','/',':',';'});
 try { if (fontStr[0]!=string.Empty) fontName = fontStr[0]; } catch { }
 try { fontSize = int.Parse(fontStr[1]); } catch { }
 try {
 if (fontStr[2].IndexOf('B')>=0) fontStyle |= FontStyle.Bold;
 if (fontStr[2].IndexOf('I')>=0) fontStyle |= FontStyle.Italic;
 if (fontStr[2].IndexOf('U')>=0) fontStyle |= FontStyle.Underline;
 } catch {}
} catch {}
Font font = new Font(fontName, fontSize, fontStyle);

允许多个分隔符( 包括空白) 并准备默认值。 iPhone 7 还没出来,我们已经在iPhone上获取细节 8,或者不管是想到下一步。 trycatch 块只有在请求没有请求的元素时才能保持默认值。

bgColorfrColorpad 执行相同的操作。 颜色问题:首先,我希望我的用户能够使用命名颜色作为 Red,或者 DarkGoldenrod 或者 ControlDark。 同时,我希望能够选择任何未命名的颜色,如 #804040。 嗯,有一个小故障我无法修复: 我不能在URL中使用 # 字符。 所以我决定在 $ 里改变它。 我认为 private 方法 StrToColor 将做其他事情,我认为它足够清晰:

private Color StrToColor(string c) {
 if (c.Trim().IndexOf("$")==0)
 return ColorTranslator.FromHtml(c.Replace("$","#"));
 elsereturn Color.FromName(c);
}

然后设置一些默认设置并解码颜色:

int pad = 0;
Color bgColor = Color.White;
Brush br = Brushes.Black;try { pad = int.Parse(Request["Padding"]); } catch { }try { bgColor = StrToColor(Request["BgColor"]); } catch { }try { br = new SolidBrush( StrToColor(Request["FrColor"]) ); } catch { }

从不同角度

有两种方法可以测量位图的大小: 测量水平呈现的字符串并使用 height 来反转 width,或者使用 StringFormatFlags.DirectionVertical ( 感谢 )Chris ) !

StringFormat format = new StringFormat(StringFormat.GenericDefault);
format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces | 
 StringFormatFlags.DirectionVertical;
SizeF sz = (Graphics.FromImage(new Bitmap(1,1))).MeasureString(Text, 
 font, Point.Empty, format);
Bitmap bm = new Bitmap((int)sz.Width+2*pad,(int)sz.Height+2*pad);

然而,以这种方式绘制字符串会带来一个感知的问题: 字符串以顶部第一个字符开始,而文本的底部则指向左侧。 当我有欧洲学校的时候,我知道易于阅读垂直文字,字符串应该是另一种方式。 这里有一些优缺点,我详细介绍。 首先,在技术绘图课程中,我学习了一个从右上角到右下角的右手的蓝图。 然后从垂直方向拖动纸张,垂直文本以自然方式变为水平方向。 然而,美国人做的另一种方式是( 像所有其他方法一样,在绘图中绘制投影) 和for标志,用于呈现垂直文本。 个人,我觉得,在一个固定的屏幕,更容易转向左侧,而不是右侧读取垂直文字( 你甚至不能把头打开)。 注意Excel在单元格中旋转文本时也遵守这里规则。

我们还可以讨论如何呈现多行垂直文本,但是对于文本框,它不会有任何差别。 但是,对于我的项目,我必须在表的标题中放置垂直标签,然后从左到右读取表列:

Table stuffed with Vertical Labels header

提示:要使竖排文本更易于阅读,请将它的设置为 Italic

所以,底线是,我们必须重新旋转文字:

System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bm);try {
 g.Clear(bgColor);
 g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
 //AntiAliasGridFit;//AntiAlias; g.TranslateTransform ((int)sz.Width,(int)sz.Height);
 g.RotateTransform(180.0F);
 g.DrawString(Text, font, br, -1-pad, 1-pad, format);

现在,在 Response 中推送位图内容并清理资源:

 MemoryStream ms = new MemoryStream();
 bm.Save(ms,ImageFormat.Png);
 Response.ContentType = "image/png";
 Response.BinaryWrite( ms.ToArray() );
 ms.Close();
} finally {
 g.Dispose();
 bm.Dispose();
 font.Dispose();
}

特殊用途

要直接从浏览器的地址栏引用 VerticalText.aspx 页面没有什么意义- 它将只呈现每个屏幕的标签。

但是,我们将使用这里引用在 SRC = 图像的属性( <Img 标记) 或者图像按钮例如在表单中使用以下代码:

<asp:ImageButtonid="ImageButton1"runat="server"ImageUrl="VerticalText.aspx?Text= Login &Font=|16|B&BgColor=Silver&FrColor=Window"BorderStyle="Outset"BorderWidth="1px"AlternateText="Login"></asp:ImageButton>

我们可能会得到一个美丽的垂直按钮:

Beautiful vertical button

现在把它打包 !

我们列表中的第二个任务是将所有的文件打包到一个易于使用的web服务- VerticalLabel。 控件必须使用它的属性的文本。字体和颜色来管理它的属性。 它还将负责呈现使用 上面 VerticalText.aspx 页面的HTML代码。 在 ToolBox 上使用一个好的标志符号来表示它是很好的。 ( 我已经讨论了创建这个小位图的挑战是什么,以及如何在 ToolBox 中使用它)。 数字文本框。)

因此,直接从中添加 VerticalLabel 控件并添加对 INamingContainer 接口的引用,这样控件就会得到一个唯一的ID。 因为它是自动生成的Text 属性,它具有 可以绑定( true ) 属性。注意控件默认情况下为 FontBackColor。 我们怀念的是我们自己添加的Padding 属性。

接下来,我们只需在 Render 方法中生成HTML代码:

protectedoverridevoid Render(HtmlTextWriter output) {
 StringBuilder s = new StringBuilder("<img ID="); s.Append(this.ID);
 s.Append(" src="VerticalText.aspx?Text="); s.Append(Text);
 s.Append("&Font="); s.Append(Font.Name); s.Append("|");

使用 StringBuilder 似乎是个好主意。 ( 尽管我们可以直接在 output 中写。 但是,这种方法可以帮助调试。) 不要将项分别添加到 + 字符串运算符中。 我们已经添加了 Font 参数,无论它的NAME 是否为空- VerticalText.aspx 页面将有一个默认的默认值。 按照相同的方式,通过规则 VerticalText.aspx 页添加 sizeFont 属性:

if (Font.Size.Unit.Value>0)
 s.Append(Font.Size.Unit.Value.ToString());if (Font.Bold || Font.Italic || Font.Underline) {
 s.Append("|");
 if (Font.Bold ) s.Append("B");
 if (Font.Italic ) s.Append("I");
 if (Font.Underline) s.Append("U");
}

如果 BackColorForeColor 没有值,不要添加它们,但是如果它是已知颜色,则使用 WebColorConverter,否则使用 ColorTranslator 转换 ToHtml。 记住,我们不能在URL中使用 # 字符,所以用 $ 替换它。

if (!BackColor.IsEmpty) {
 s.Append("&BgColor=");
 s.Append(((BackColor.IsKnownColor)
?(new WebColorConverter()).ConvertToString(BackColor)
 :ColorTranslator.ToHtml(BackColor).Replace("#","$")));
}if (!ForeColor.IsEmpty) {
 s.Append("&FrColor=");
 s.Append(((ForeColor.IsKnownColor)
?(new WebColorConverter()).ConvertToString(ForeColor)
 :ColorTranslator.ToHtml(ForeColor).Replace("#","$")));
}if (Padding>0) {
 s.Append("&Padding=");
 s.Append(Padding.ToString());
}
s.Append(""");

如果在 VerticalText.aspx 页面中出现错误,就需要一个水平文本,添加 ALT = HTML组件的属性。 这可以能有点奇怪,因为Alt文本变成了一个完全相同的标签,因这里可以保留或者丢弃下一行:

s.Append(" Alt=""); s.Append(Text); s.Append("""); //!

关闭标签并将所有内容写到 output。 调试时,可以在输出语句或者任何 上面 上放置断点,以查看字符串的累积方式。

 s.Append(">");
 output.Write(s.ToString());
}

愿望列表

希望我能够在 VerticalLabel 控件的程序集中包含 VerticalText.aspx 页。 这似乎是不可能的- 页面应该是最终程序集的一部分,或者是一个单独的程序集。 上面 代码包括程序集的完整路径,控件应该包含指向程序集URL的属性,并且用户必须在项目中键入该URL种子;用户可能会在最终程序集中键入该URL种子,而不需要进行任何更改。

写完这个项目之后,asp.netPRO magazine ( 2004 )"自定义HTTP处理程序"这篇文章suggesting可以使用接口接口实现与 VerticalText.aspx 页面相同的效果。 我可以能很快进入,但重新配置IIS和 Having 上的处理程序的价格似乎太高了。 也许有一些附加的功能作为可变角度,图形效果,以及从数据库或者其他来源检索背景/水印图像。

我希望能够在标签的标题或者未知颜色的规范中包含 &# 之类的字符。

这里描述的技术不支持透明位图。 这里有一篇很好的文章- 关于着色gif并使它的透明,但是代码 transparent,代码 stuffy stuffy,我的项目不需要在这里 include。

也许,我将从你那里得到一些好的建议。


WEB  Vertica  Labels  
相关文章