  
- UID
- 2031431
- 威望
- 27 点
- 金钱
- 2 金币
- 点卡
- 10 点
|
2#
发表于 2004-5-14 23:39
| 只看该作者
[分享]验证码技术及其实现
上面的转自http://blog.94cool.net
用XBM创建动态客户端图像
作者: BUILDER.COM
Wednesday, April 9 2003 11:23 AM
X-Bitmap(XBM)是一种古老但通用的图像文件格式,它与现在的许多Web浏览器都兼容。X-Windows图形界面(UNIX和Linux常用的GUI)的C代码库xlib中有一个组件专门描述了它的规范。我将解释XBM格式的工作原理,然后向你展示一种更有趣的使用它的方法:在客户端创建动态图像。文章中的代码可以在此下载。
XBM基础
XBM格式本来是为存储单色的系统位图而设计的,比如图标和鼠标指针。XBM图形的实质上是使用16进制数组来表示二进制图像的C源代码文件。(16进制数组表示的二进制图像)
这里你也许会问:这种文件格式与Web浏览器有什么关系?在上世纪九十年代早期,美国超级计算应用中心(NCSA)在伊利诺斯大学开发第一个被广泛使用的Web浏览器,名为Mosaic。这个浏览器的图形支持来自很多开放源码代码库,其中就包括xlib。因此,导致今天的许多浏览器能够处理XBM图形。
Mosaic项目后来成为了Netscape浏览器的开发基础。微软也借用了一部分Mosaic代码来创建Internet Explorer。微软继而在网络信息服务器(IIS)中将XBM作为一个MIME类型注册而提供本地支持,并且在现有所有版本的Internet Explorer中将其作为一种可支持的图像。(浏览器的广泛支持)
从一个程序员的角度来看,JPEG或GIF与XBM有着极大的不同。这两种文件格式都在位级别上操作并使用了压缩算法。它们可以支持很大的颜色深度范围。创建这些动态Web图形的唯一方法是使用服务器端的脚本,比如<a href=http://stein.cshl.org/WWW/software/GD/GD.pm和CGI/Perl脚本的结合,或者通过System.Drawing名字空间访问ASP.NET中的图形设计接口类库(GDI+)。(升级到ASP.NET有很多个理由。)
XBM创建起来很有程序性。每个位都被一一指定,而结果图形被限制为两色(黑色和白色)。(局限性之一:让人不爽)X-Bitmap并不是必须服务器端脚本,可以在客户端用JavaScript实时创建它们。(增加了不少灵活性)
X-Bitmap的实用程序包括动态生成的图、页面计数器、老式图形图标、以及统计图表。(就是通过位控制太麻烦了,有良好的包装就好了。另外:生成图片的大小,算法的强度,是否都达到了可用的要求?)给我印象最深的XMB应用是一个叫Wolfenstein 5k的游戏,它是一个纹理映射的第一视角射击游戏,用JavaScript编写,只有5KB大小。(不错啊,稍后爽一下)
通过使用IMG标识可以很容易地将XBM文件嵌入到一个Web页面中。其语法如下:
<img src=”xbmsmill.xbm”>
----------------------------------------------------------------------
注意
这种格式不对Mac或相应的浏览器有效,比如Mozilla的早期版本。
----------------------------------------------------------------------
典型的XBM源代码与列表A中显示的比较相像。
#define语句以像素点为单位设置了图像的宽度和高度。你也可以使用x_hot和y_hot命令来定义图像中的一个热点。我已经创建了一个X-Bitmap来描绘这个过程。为了设计它,我先将图像映射为二进制值,如果你仔细的看,在这里你会看到一张笑脸。
我所创建的二进制图像宽16个数字高7个数字,在我们的源代码的XBM头中定义了相同大小的宽/高像素值。图像本身被存储在一个静态数组中,它包含一列二进制编码的十六进制(BCH)值——换句话说,每四位分成一组。
计算出笑脸的十六进制值得最简单的方法是一次检验图像的一行,将二进制值分成四位一组的分段,将每个分段映射成二进制/十六进制表中对应的十六进制数。下面是第一行:
0001100001100000
下面两行分别表示四位的分段和其在表A中对应的十六进制数
二进制: 0001 1000 0110 0000
十六进制: 8 1 6 0
表A
XBM二/十六进制转换表
二进制 十六进制
0000 0
1000 1
0100 2
1100 3
0010 4
1010 5
0110 6
1110 7
0001 8
1001 9
0101 A
1101 B
0011 C
1011 D
0111 E
1111 F
请注意这些并不是标准的二/十六进制转换。它们是反向计算的(从左到右)而不是从右到左。把它颠倒是因为浏览器会从左到右来读图形,我们的代码必须与其一致。
最后要把这些十六进制值转换成XBM的右格式。必须在每个十六进制值前加“0x”。这是标准C++表示十六进制的方法。然后将这些值从右到左输出(每个十六进制对表示八位二进制位)。请看列表B中的例子。
因此,我们可以说:
0001100001100000=0x18,0x06
这些符合XBM的值可以很容易地插入到图像数组中:
static unsigned char xbmsmile_bits[]=
现在我们来看看格式本身,现在是时候来学习在客户端浏览器中动态创建X-Bitmap了。
图片用点阵的形式表示,比如2:
00111100 0011为3 1100为C 即0x3c
01100110 0110为6 0110为6 0x66
01100000 ....... 0x表示十六进制数。
01100000 依此类推
00110000 这是用二进制数得到的点阵,其中的1为显示一黑点,0不显示
00011000 是一个反着看的2
00001100 其余数字可自已排列点阵再二进制化为十六进制数
00000110 缺点是只有黑白两种颜色
00000110 显示出来是白底黑字,要显示黑底白字的话,对其取反就行了
01111110
下面是我"画"的0-9的数字
num.asp
<%
Dim a(10,10)
a(0,1) = "0x3c" '数字0
a(0,2) = "0x66"
a(0,3) = "0xc3"
a(0,4) = "0xc3"
a(0,5) = "0xc3"
a(0,6) = "0xc3"
a(0,7) = "0xc3"
a(0,8) = "0xc3"
a(0,9) = "0x66"
a(0,10)= "0x3c"
a(1,1) = "0x18" '数字1
a(1,2) = "0x1c"
a(1,3) = "0x18"
a(1,4) = "0x18"
a(1,5) = "0x18"
a(1,6) = "0x18"
a(1,7) = "0x18"
a(1,8) = "0x18"
a(1,9) = "0x18"
a(0,10)= "0x7e"
a(2,1) = "0x3c" '数字2
a(2,2) = "0x66"
a(2,3) = "0x60"
a(2,4) = "0x60"
a(2,5) = "0x30"
a(2,6) = "0x18"
a(2,7) = "0x0c"
a(2,8) = "0x06"
a(2,9) = "0x06"
a(2,10)= "0x7e"
a(3,1) = "0x3c" '数字3
a(3,2) = "0x66"
a(3,3) = "0xc0"
a(3,4) = "0x60"
a(3,5) = "0x1c"
a(3,6) = "0x60"
a(3,7) = "0xc0"
a(3,8) = "0xc0"
a(3,9) = "0x66"
a(3,10)= "0x38"
a(4,1) = "0x38" '数字4
a(4,2) = "0x3c"
a(4,3) = "0x36"
a(4,4) = "0x33"
a(4,5) = "0x33"
a(4,6) = "0x33"
a(4,7) = "0xff"
a(4,8) = "0x30"
a(4,9) = "0x30"
a(4,10)= "0xfe"
a(5,1) = "0xfe" '数字5
a(5,2) = "0xfe"
a(5,3) = "0x06"
a(5,4) = "0x06"
a(5,5) = "0x3e"
a(5,6) = "0x60"
a(5,7) = "0xc0"
a(5,8) = "0xc3"
a(5,9) = "0x66"
a(5,10)= "0x3c"
a(6,1) = "0x60" '数字6
a(6,2) = "0x30"
a(6,3) = "0x18"
a(6,4) = "0x0c"
a(6,5) = "0x3e"
a(6,6) = "0x63"
a(6,7) = "0xc3"
a(6,8) = "0xc3"
a(6,9) = "0x66"
a(6,10) ="0x3c"
a(7,1) = "0xff" '数字7
a(7,2) = "0xc0"
a(7,3) = "0x60"
a(7,4) = "0x30"
a(7,5) = "0x18"
a(7,6) = "0x18"
a(7,7) = "0x18"
a(7,8) = "0x18"
a(7,9) = "0x18"
a(7,10)= "0x18"
a(8,1) = "0x3c" '数字8
a(8,2) = "0x66"
a(8,3) = "0xc3"
a(8,4) = "0x66"
a(8,5) = "0x3c"
a(8,6) = "0x66"
a(8,7) = "0xc3"
a(8,8) = "0xc3"
a(8,9) = "0x66"
a(8,10)= "0x3c"
a(9,1) = "0x3c" '数字9
a(9,2) = "0x66"
a(9,3) = "0xc3"
a(9,4) = "0xc3"
a(9,5) = "0x66"
a(9,6) = "0x3c"
a(9,7) = "0x18"
a(9,8) = "0x0c"
a(9,9) = "0x06"
a(9,10)= "0x03"
%>
显示的方法是:
1.先传出一个MIME:
Response.ContentType = "image/x-xbitmap"
2.再传出一个c++的源程序,如显示2:
#define counter_width 8
#define counter_height 10
static unsigned char counter_bits[] = {
0x3c,0x66,0x60,0x60,0x30,0x18,0x0c,0x06,0x06,0x7e
};
这样在浏览器上就显示出来一个8*10像素的2了
要显示两个或以上的数字的时候,须改动宽度的值(必须是图像点阵宽度的整数倍),在count_bits[]数组的值排序如下:
比如显示 12
a(1,1), a(2,1), a(1,2), a(2,2)... a(1,10), a(2,10)
下面是具体计数器的例子:
count.asp
<!--#include file="num.asp"-->
<%
Dim Image
Dim Width, Height
Dim num
Dim digtal
Dim Length
Dim sort
Length = 10 '自定计数器长度
Redim sort( Length )
num = 62275 '计数器的值
digital = ""
For I = 1 To Length -Len( num ) '补0
digital = digital & "0"
Next
For I = 1 To Len( num )
digital = digital & Mid( num, I, 1 )
Next
For I = 1 To Len( digital )
sort(I) = Mid( digital, I, 1 )
Next
Width = 8 * Len( digital ) '图像的宽度
Height = 10 '图像的高度,在本例中为固定值
Response.ContentType="image/x-xbitmap"
hc=chr(13) & chr(10)
Image = "#define counter_width " & Width & hc
Image = Image & "#define counter_height " & Height & hc
Image = Image & "static unsigned char counter_bits[]={" & hc
For I = 1 To Height
For J = 1 To Length
Image = Image & a(sort(J),I) & ","
Next
Next
Image = Left( Image, Len( Image ) - 1 ) '去掉最后一个逗号
Image = Image & "};" & hc
Response.Write Image
%>
把
#define counter_width 8
#define counter_height 10
static unsigned char counter_bits[] = {
0x3c,0x66,0x60,0x60,0x30,0x18,0x0c,0x06,0x06,0x7e
};
保存为 xbm 文件就可以得到一张显示为 2 的图片
#define counter_width 80
#define counter_height 10
static unsigned char counter_bits[]={
0x3c,0x3c,0x3c,0x3c,0x3c,0x60,0x3c,0x3c,0xff,0xfe,0x66,0x66,0x66,0x66,0x66,0x30,0x66,0x66,0xc0,0xfe,0xc3,0xc3,0xc3,0xc3,0xc3,0x18,0x60,0x60,0x60,0x06,0xc3,0xc3,0xc3,0xc3,0xc3,0x0c,0x60,0x60,0x30,0x06,0xc3,0xc3,0xc3,0xc3,0xc3,0x3e,0x30,0x30,0x18,0x3e,0xc3,0xc3,0xc3,0xc3,0xc3,0x63,0x18,0x18,0x18,0x60,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x0c,0x0c,0x18,0xc0,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x06,0x06,0x18,0xc3,0x66,0x66,0x66,0x66,0x66,0x66,0x06,0x06,0x18,0x66,0x7e,0x7e,0x7e,0x7e,0x7e,0x3c,0x7e,0x7e,0x18,0x3c};
保存为 xbm文件则显示为 0000062275 。 |
哈哈哈!!!!你的IP是不是 ?我都知道了!!! |
|