仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1646|回复: 19
打印 上一主题 下一主题

[学习教程] PHP教程之在 PHP 顶用描点法“绘制”中文

[复制链接]
再见西城 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-2-4 00:20:19 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
当然你可以把你最基本的功能放出来的时候就放出来,比如放到论坛上,让大家都参与,中文   作者:LuciferStar 来历:超出PHP

媒介:
如今,愈来愈多的人喜好上彀了,愈来愈多的人具有了本人的团体主页。跟着各类主动化软件东西的呈现,制造网页愈来愈复杂。但,因为殊效到处可得,立异的器材,愈来愈少。说不定,哪天,你会发明某个网站上的计数器和本人的如出一辙。网页越做越干练。网页上的器材,也愈来愈多,愈来愈丰厚。
设问:

在网页上,假如我要添加一个计数器:
之前,那就去空间供应商那边要个链接,或其他中央去复制个地址,但这一些,总归是他人做的,好欠好,你是没有太多的讲话权的,只能一个一个地找。
在网页上,我要将一些信息宣布出去:
假设信息是文本,做一个新页面,加个链接;
是数据,做一个新页面,加个链接:
可如果这些数据常常更新,乃至,每小时、每分钟,都能够会改动,你是不是情愿守在电脑前,一直修正、上传呢?(咱可不是贸易网站,没有人情愿为你而烧钱。)
而留言板、聊天室、服装论坛,这些,决不是单靠HTML和JAVASCRIPT就可以弄定的。
为了完成更多的主动掌握,可使用CGI(Common Gateway Interface)法式来完成这些功效。

软件需求:
PHP:GD Library
设置装备摆设撑持PHP的办事器。我用OmniHTTPd Professional

关于计数器和及时数据统计、宣布,咱们可以用图片来完成。在图片中输入文字。
在PHP中,要创立一个图片,并在下面显示点内容,根基步调以下:


<?php
//http头,告知阅读器,这是一个GIF图片
header ("Content-type: image/gif");
// 要画画,先要有花布不是?创立一个400×300调色板图象
$im = imagecreate (400, 300);
$black = imagecolorallocate ($im, 0, 0, 0);
// 默许黑色后台。
//(默许,是指第一个界说的色彩。假如在此行代码后面界说了另外一个色彩,那末,最早界说的谁人,就是默许后台色彩。)
$red = imagecolorallocate ($im, 255, 0, 0);
//白色。假如这两行互换,你会发明后台是白色,文字是黑色。
$string="1234567890";
// 要绘制的字符
imagestring ($im,12,10,10,$string,$red);
//在(10,10)入手下手绘制字符串
imagepng ($im);
// 以png格局输入,也能够用imagejpeg($im);或magegif($im);但后者,假如GD版本高于1.6,就不克不及用了。
imagedestroy ($im);
// 停止,排除一切占用的内存资本
?>

下面示例,在400×300的图片上,自点(10,10)入手下手,绘制12磅的"1234567890"。你有无注重到这张图片的巨细是:251字节!你也能够尝尝其他的输入格局。
图片的巨细,与图片中非后台象素点数有关,跟输入几何象素有关。

但是,有一个成绩。
你可以用imagestring()输入以下的信息:
imagestring($im,1,0,0,"abcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&*()_+{}|:"<>?[]';,./",$red);
可是,你没法准确输入中文!!!
imagestring($im,1,0,0,"啊",$red);
你看到的,决不是中文!!而是乱码。
PHP默许的字符集是UTF-8,而简体中文是GB2312。

若何处理?!
为懂得决这个成绩,你可让PHP加载扩大模块php_iconv.dll(UNIT下的后缀名是.SO),不外,有时分,能够不克不及正常任务。原本,我要把一段测试代码放下去,可此次,怎样弄都没有胜利。为了不毛病,我仍是不把它们放下去了。
但,最致命的,假如你的空间办事商封闭了该扩大模块,或,乃至制止了加载模块的DL()函数,那,你就只能跟中文BYE-BYE了。
还好,还有其他举措。
可以经由过程字符映照,将事后转换好的码表中字符输入来。但,你需求一张码表!
或,手工绘制每个中文的每个点!感到怎样?!

好,来吧,咱们一同来画字!

画字,起首要晓得怎样画。
初中的复杂函数,学过吧?要画出函数的图形,做过吧?算出某点的坐标,然后毗连两相邻点。这类办法,叫描点法。
咱们要做的,是尽可能多地将点算出来,然后在响应坐标显示出来。
你是不是传闻过点阵打印机、点阵汉字?
在输入汉字时,它们是用一个个点来暗示的。

在某个坐标上显示一个某种色彩的点的函数是:
int imagesetpixel ( resource image, int x, int y, int color)
假定我要在座标(100,100)处显示一个白色的点,那末,只需以下代码:


<?php
header ("Content-type: image/gif");
$image = imagecreate (400, 300);
$black = imagecolorallocate ($image, 0, 0, 0);
$white = imagecolorallocate ($image, 255, 255, 255); // 界说白色
imagesetpixel ( $image, 100, 100, $white);
imagepng ($image);
imagedestroy ($image);
?>

也就是说,咱们只需获得某个汉字的一切点的信息,咱们就可以够经由过程这个函数,输入谁人汉字。

在文件chs16.fon里,保留的,是国标区位码表(国度尺度信息互换用汉字编码根基字符集GB-2312)。它是汉字的点阵字库。(WIN98体系中,此文件在c:windowscommand下。假如你要把它放在UNIX体系下利用,请注重巨细写。假如没有,你可以在文末找到链接。)
它是MSDOS时期的,但,好器材,仍是应当拿出来一用的。

从chs16.fon里,咱们可以读取汉字的点阵数据。每一个汉字,都是由16×16个点组成的。笔画走过的中央,点的值为1,不然为0;每一个点占用一个位,每8个点组成一个字节。那末,一个汉字,就需求(16×16÷8=32)字节。

上面这个实例,是为了申明字符点阵的暗示办法。
这里,界说了一个8×8的矩阵,显示了一个字母C,白色的方块用0暗示,黑色方块用1暗示,那末,这八行图形的代码分离是:




二进制暗示
十六进制暗示

0
00000000
0x00

1
00111110
0x3E

2
01110000
0xE0

3
01110000
0xE0

4
01110000
0xE0

5
01110000
0xE0

6
00111110
0x3E

7
00000000
0x00




要输入这些点的话,就需求先画第一行,然后第二行、第三行……到最初一行。
用一个轮回:
for($hang=0;$hang<8;$hang++)
在每行中,有八个格子,需求分离绘制,从第一个,然后第二个、第三个……到最初一个。
用一个轮回:
for($gezi=0;$gezi<8;$gezi++)
两个轮回联列:
for($hang=0;$hang<8;$hang++)
for($gezi=0;$gezi<8;$gezi++)
{ //在这里,咱们就可以输入点了。
imagesetpixel ( $image, $gezi, $hang, $color);
}

但,咱们若何晓得到哪里去读某个汉字的点阵数据呢?

普通的字符,好比ASCII码,是用数字0--127(即二进制00000000到01111111)来暗示,而中文,则是用两个高位为1的字节(100000000 100000000)暗示。如: 半角字符"A",机内码为 (01000001)(它实践上是ASCII码值)。
上面,让咱们翻开"字符映照表"看看吧。假如你为了节俭磁盘,没有装置,那就装一下,不大。假如不会装置,那你就接下去看我乱侃吧。
在字符映照内外,字体选择"楷体_GB2312",点击"特别符号",这时候,你可以看到国标区位码表,从字符(10110000 10100001)入手下手,一向到(10011111 11111111)。
全角字符"A",机内码为:(10100011 11000001)(它实践是两个高位为1的ASCII码)。
中文"啊"的机内码,是(10110000 10100001);
在GB-2312字符集中,"啊"在表中地位是第16区第1位,这个坐标(16,1),用二进制暗示,就是(00010000,00000001)。这,就是"啊"的区位码。
请看:

中文字符: 啊
机内码: (10110000 10100001)
区位码: (00010000,00000001)
相差: (10100000,10100000)

所以,
区位码与机内码的换算公式为 【区位码】+(10100000 10100000)=【机内码】。即:
区位码0 + (10100000) = 机内码0;
区位码1 + (10100000) = 机内码1;
如许的话,点阵数据,就能够经由过程汉字"机内码"-> "区位码"停止索引、查找。

后面已讲了一个汉字,在表中要占用32字节,所以,咱们界说了一个含有32个元素的数组:
$buffer=array(0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0,0,0,0,
0,0);
用来保留从字库读出的32个字节数据。

接上去的成绩,某一个字符,究竟保留在文件的甚么地位呢?

因为一个汉字用了32个字节,而GB-2312区位码表表有94行、94列,那末,只需晓得该字符在表中是第几个,再乘以32就好了。
所以界说偏移量:
$offset=(94*($qh-1)+($wh-1))*32;
$qh暗示区(qu)、$wh暗示位(wei);减1,是由于PHP从0入手下手计数。
地位找到,就只需求用fseek()函数定到码表的这个地位,然后读32字节到$buffer就好了。
别的,因为中文是由两个字节构成,而后面给出的点阵示例是8位,一个字节,所以,画点的代码要修正一下:
for($hang=0;$hang<16;$hang++)
for($j=0;$j<2;$j++) //由于是两个字节,所以拔出一个轮回
for($gezi=0;$gezi<8;$gezi++)
{
imagesetpixel ( $image, $gezi +8*$j, $hang , $color);
}

好,咱们入手下手编程吧!


/*************************************
* 文件名:'draw1.0.inc.php
** 中文显示点阵输入 version 1.0
** 只供应复杂的操作:输入默许巨细的纯中文字符串到图片的坐标(0,0)上
** 更多功效,请见下一版本。
*
****************************************/
function draw($image,$string,$color)
{
$fp=fopen("chs16.fon","rb");//二进制体例读点阵字库chs16.fon
if (!feof($fp))//假如文件指针到了文件末尾,加入,不要健忘封闭文件
{
while($string)//当字符串不为0
{
$qh=ord(substr($string,0,1))-0xa0;
$wh=ord(substr($string,1,2))-0xa0;
/* 这两行代码,实际上是获得一个中文的机内码。
substr($string,0,1);是从$string中获得第一个字节,然后,经由过程ord();将这个字符转换为整数。(因为PHP不撑持无符号整数,所以没有这一步转换的话,你就只能失掉一个0。)在转换为整数以后,就可以停止盘算了。机内码减去0xa0(10100000),就失掉了区位码。
substr($string,1,2);是获得$string中的第二个字节。*/
$offset=(94*($qh-1)+($wh-1))*32;
/*失掉了汉字的区位值后,就入手下手盘算偏移量了。*/
fseek($fp,$offset,SEEK_SET);
/*在字库文件$fp中,将文件指针定位到偏移量。*/
$buffer=preg_split('//', fread($fp,32), -1, PREG_SPLIT_NO_EMPTY);
/* fread($fp,32);是从$fp中读取32个字节数据,然后经由过程preg_split();分派到数组$buffer中。preg_split();是一个撑持正则表达的函数。关于正则表达式,我正在进修中。为何如许用,我也不晓得。PHP手册里有本实例。*/
for($i=0;$i<16;$i++) //点阵的行数:16 列数也应当是16
for($j=0;$j<2;$j++) //由于是两个字节,那末,就要一个一个地画了
for($k=0;$k<8;$k++) //每一个字节,都有8个点的数据
if(((ord($buffer[$i*2+$j])>>(7-$k))&0x01))//假如这个点的值为1,输入;不然,没有
{
imagesetpixel($image,$x+8*$j+$k, $i, $color);
}
$string=substr($string,2); //中文由两个字节暗示,所以,输入一个汉字后,就要去失落两个字节。
$x=24; //一个汉字输入停止,空开一点,给下一个汉字。由于这个汉字是16×16点,那末,$x的值设为16,就够了。但,太挤了不是?
}
}
fclose($fp);
}
上面,我给出一个测试实例:


<?php
header ("Content-type: image/gif");
include 'draw1.0.inc.php';
$im = imagecreate (400, 300);
$black = imagecolorallocate ($im, 0, 0, 0);
$string="中文";
drawer($im,$string);
imagepng ($im);
imagedestroy ($im);
?>

关于这个函数,咱们还可以停止扩大,以完成分歧的后果。


  在学习PHP这六个月里,每看到一个优秀的php脚本,就会兴奋的手舞足蹈,嘴里还不停的说:太酷了,太酷了。呵呵,很幼稚吧,但这可能就是兴趣。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-5-23 11:19

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表