首页=>开发=>VB/VB.NET=>随心所欲产生图案 |
|
|
随心所欲产生图案 |
www.51study.net 2004-10-23 22:25 |
【字体:大 中 小】【评论】【打印】 【关闭】 |
|
|
要是没有外部的组件支持,有一些东西是 ASP 无法办到的,也就是动态产生图案 - 不管是图表、横幅广告、或是简单的图形计数器。幸运的是,这在 ASP.NET 中已经改变了 - 使用内建的方法,图案可以动态产生以及能够用最大限度的组态设定能力传送到 client 端,且很容易办到。 使用本文章的原始程序代码必须在 Webserver 安装 Microsoft .NET Framework SDK。同时我也假设读者对 C# 程序有一定程度的认识。 产生图案 在还没感受到 ASP.NET 庞大压力下,我做了一个较乏味简单的指令行程序,然后使用这个原始程序代码作为我们 ASP.NET script 的基础。所不同的是这个指令行会将图案储存为一档案,而 ASP.NET script 将他送到 client 端。 现在,我们的范例程序做了什么?就像一般常见的,一开始我们使用一般喜欢用的 "Hello World" 程序,文字会输出成一图案文件,然后图案会依据目前所选定的字型以及字号,产生同样大小的 "Hello World" 文字(因此,要产生特大的图像就无法计算) 下面的 Script (pagecounter.cs) 是典型简单的指令行程序: 忽略包裹在周围的 class , 只有函式 Main执行时会被呼叫,这也就是我们产生图案所在的程序。 using System; using System.IO; using System.Drawing; using System.Drawing.Imaging; public class CTestBitmapFunctionality { public static void Main() { Bitmap newBitmap = null; Graphics g = null ; try { Font fontCounter = new Font("Lucida Sans Unicode", 12); // calculate size of the string. newBitmap = new Bitmap(1,1,PixelFormat.Format32bppARGB); g = Graphics.FromImage(newBitmap); SizeF stringSize = g.MeasureString("Hello World", fontCounter); int nWidth = (int)stringSize.Width; int nHeight = (int)stringSize.Height; g.Dispose(); newBitmap.Dispose(); newBitmap = new Bitmap(nWidth,nHeight,PixelFormat.Format32bppARGB); g = Graphics.FromImage(newBitmap); g.FillRectangle(new SolidBrush(Color.White), new Rectangle(0,0,nWidth,nHeight)); g.DrawString("Hello World", fontCounter, new SolidBrush(Color.Black), 0, 0); newBitmap.Save("c:\\test.png", ImageFormat.PNG); } catch (Exception e) { Console.WriteLine(e.ToString()); } finally { if (null != g) g.Dispose(); if (null != newBitmap) newBitmap.Dispose(); } } } 这程序做了什么?不管怎样,结果图案 test.png 会储存在 drive c: 图案如何产生?为了解原因,我们必须详细来看一下原始码。首先,图案大小必须是和要呈现的文字字型 "Hello World" 大小一样,因此,我会先计算文字大小,同时为达目的,我使用一个 size 1 x 1 的仿制图案,当我计算完成,我抓取图案然后产生一适当的大小图案。 原始码中有趣的一点是 Graphics 对象。当我要产生图像为何需要这对象呢? 理由是这是我要画进去的图案情境 (context) - 我可以在屏幕、打印机以及内存使用图案情境 - 正确来说就是 Bitmap。图案情境允许我在任何设备执行绘图操作 (既时是虚拟的)。 使用 DrawString,我现在可以根据白色背景 (使用 FillRectangle 产生) 的长方形规格输出文字 "Hello World"。图案完成了,我必须把它存到磁盘中。曾经有过自己设计过图案文件格式都知道这是一件困难的事,使用 GDI+ (Graphics Device Interface) 就不是如此 - 我们只要使用一简单的命令就行了: newBitmap.Save("c:\\test.png", ImageFormat.PNG); 就这样了! 只要将 ImageFormat.PNG 交换成 ImageFormat.JPEG,你就能有 jpeg 的档案。简单的使用图案,这就是我们一直想要的。 现在只是有个例外处理有待解释:一些函式会造成例外(例如,没有足够的内存来产生图像)。好的程序设计者必须能够自行清除,我必须处理释放 Graphics 和 Bitmap - 而这也就是我在 finally 区块所做的 (因为他总是会被呼叫)。而在 finally 之后程序结束。 理论上来说,这个程序可以运作,但仅在原始码中,要让它实际来执行,必须先经过编译: csc /R:System.DLL /R:System.Drawing.DLL pagecounter.cs 这样我们可以产生一 .EXE 檔 pagecounter.exe。注意:这个档案在系统安装 Microsoft .NET framework 后才能执行喔! 现在 web server 上的工作 当作指令行应用程序执行起来相当棒,但如果作为 ASP.NET script 就必须使用一些小技巧: 可选择的文字 (例如,计数器) 可选择的文字颜色 可选择的背景颜色 可选择的字型 可选择的字号 如果有人感到这有点困难的话,你可以先看一下这个图案的 ASP.NET script 档案 (pagecounter.aspx) 的原始码 原始码。 我所必须做的是加入一些错误处理程序代码来检查传送的验证参数。这可说是必须改变的最大部分。 另外必须做的是将图案送到 client 端,而不是将它写入成为一个档案。这个新部分如下: MemoryStream tempStream = new MemoryStream(); newBitmap.Save(tempStream,ImageFormat.PNG); Response.ClearContent(); Response.ContentType = "image/png"; Response.BinaryWrite(tempStream.ToArray()); Response.End(); 我只是将图案放入内存缓冲区,然后传送到这个熟悉的函式 BinaryWrite 是为字节,同时:我需要这个函式 ClearContent,因为在这 Script 的最上部分有 Import 指令会送出空白列到 client 端,使得 PNG 图档无效。 如果你有仔细看一下 原始码,将会注意到我已经传送所有可选择的参数作为 querystring 参数。这样参数可能太长,因此向我这样的懒人,我自己建构了一个看起来舒适一点的窗体 (form),这样我就能测试各种不同的值 〔注〕这张图案原先文字是德文,我在自己机器上测试将文字转成中文,因此,下载原始档是使用德文,你必须自己改成中文字。 这个 ASP.NET page (pagecountertest.aspx) 更棒的是我可以在同一个网页获得图案。这个 form 的 原始码 已经包含许多 server 端的 ASP.NET 控件 (controls)。 这意味着可作为将来文章中的开胃菜,在 ASP.NET 架构中对于 form 的处理以及验证,会有详尽说明。 结论 在这篇文章中我们以飞速来看图案程序的一些特征。对于我们的网站计划, ASP.NET 架构中现在能提供 web page 程序设计者对于 Windows 图案程序设计完整的使用操作。现在我们可以将 " 办不到 " 这句话拋之脑后了。 |
|
|
【字体:大 中 小】【评论】【打印】 【关闭】 |
|
|
|
|
|