随心所欲产生图案
January 9th, 2009 by 来自网络
使用本文章的原始程序代码必须在 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 图案程序设计完整的使用操作。现在我们可以将 " 办不到 " 这句话拋之脑后了。
#If you have any other info about this subject , Please add it free.# |
- Posted in jsgp.com edit