再见西城 发表于 2015-2-4 00:20:19

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

当然你可以把你最基本的功能放出来的时候就放出来,比如放到论坛上,让大家都参与,中文   作者: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脚本,就会兴奋的手舞足蹈,嘴里还不停的说:太酷了,太酷了。呵呵,很幼稚吧,但这可能就是兴趣。

精灵巫婆 发表于 2015-2-4 11:56:31

其实没啥难的,多练习,练习写程序,真正的实践比看100遍都有用。不过要熟悉引擎

灵魂腐蚀 发表于 2015-2-9 22:28:58

说php的话,首先得提一下数组,开始的时候我是最烦数组的,总是被弄的晕头转向,不过后来呢,我觉得数组里php里最强大的存储方法,所以建议新手们要学好数组。

山那边是海 发表于 2015-2-11 02:15:00

找到的的资料很多都是在论坛里的,需要注册,所以我一般没到一个论坛都注册一个id,所有的id都注册成一样的,这样下次再进来的时候就不用重复注册啦。当然有些论坛的某些资料是需要的付费的。

海妖 发表于 2015-3-1 17:06:52

php里的数组为空的时候是不能拿来遍历的;(这个有点低级啊,不过我刚被这个边界问题墨迹了好长一会)

仓酷云 发表于 2015-3-6 21:39:25

至于模板嘛,各位高人一直以来就是争论不休,我一只小菜鸟就不加入战团啦,咱们新手还是多学点东西的好。

老尸 发表于 2015-3-7 00:37:22

建数据库表的时候,int型要输入长度的,其实是个摆设的输入几位都没影响的,只要大于4就行,囧。

若相依 发表于 2015-3-7 22:37:52

写js我最烦的就是 ie 和 firefox下同样的代码 结果显示的结果千差万别,还是就是最好不要用遨游去调试,因为有时候遨游是禁用js的,有可能代码是争取结果被遨游折腾的认为是代码写错。

admin 发表于 2015-3-13 11:08:44

使用 jquery 等js框架的时候,要随时注意浏览器的更新情况,不然很容易发生框架不能使用。

小女巫 发表于 2015-3-15 14:59:33

建数据库表的时候,int型要输入长度的,其实是个摆设的输入几位都没影响的,只要大于4就行,囧。

简单生活 发表于 2015-3-22 22:35:41

真正的方向了,如果将来要去开发团队,你一定要学好smarty ,phplib这样的模板引擎,

小魔女 发表于 2015-4-6 23:08:38

如果你可以写完像留言板这样的程序,那么你可以去一些别人的代码了,

金色的骷髅 发表于 2015-5-1 09:12:14

,熟悉html,能用div+css,还有javascript,优先考虑linux。我在开始学习的时候,就想把这些知识一起学习,我天真的认为同时学习能够互相呼应,因为知识是相通的。

不帅 发表于 2015-5-2 19:55:07

学习php的目的往往是为了开发动态网站,phper就业的要求也涵盖了很多。我大致总结为:精通php和mysql

只想知道 发表于 2015-5-10 04:46:36

对于初学者来说不推荐去拿钱买的。当然如果一个网站你经常去用,而且里面的资料也比较有用,最好还是买个会员比较好,毕竟那些也是别人的工作成果。

分手快乐 发表于 2015-6-4 02:11:30

说php的话,首先得提一下数组,开始的时候我是最烦数组的,总是被弄的晕头转向,不过后来呢,我觉得数组里php里最强大的存储方法,所以建议新手们要学好数组。

若天明 发表于 2015-6-5 23:56:17

使用 jquery 等js框架的时候,要随时注意浏览器的更新情况,不然很容易发生框架不能使用。

柔情似水 发表于 2015-6-27 04:46:49

小鸟是第一次发帖(我习惯潜水的(*^__^*) 嘻嘻……),有错误之处还请大家批评指正,另外,前些日子听人说有高手能用php写驱动程序,真是学无止境,人外有人,天外有天。

兰色精灵 发表于 2015-7-9 20:54:51

为了以后维护的方便最好是代码上都加上注释,“予人方便,自己方便”。此外开发文档什么的最好都弄齐全。我觉得这是程序员必备的素质。虽然会消耗点很多的时间。但是确实是非常有必要的。

admin 发表于 2015-7-10 17:01:26

遇到出错的时候,我经常把错误信息直接复制到 google的搜索栏,一般情况都是能搜到结果的,不过有时候会搜出来一大片英文的出来,这时候就得过滤一下,吧中文的弄出来,挨着式方法。
页: [1]
查看完整版本: PHP教程之在 PHP 顶用描点法“绘制”中文