热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在PHP中用描点法“绘制”中文

文章标题:在PHP中用描点法“绘制”中文。Linux是中国IT实验室的一个技术频道。包含桌面应用,Linux系统管理,内核研究,嵌入式系统和开源等一些基本分类

  前言:
  现在,越来越多的人喜欢上网了,越来越多的人拥有了自己的个人主页。随着各种自动化软件工具的出现,制作网页越来越简单。但,由于特效随处可得,创新的东西,越来越少。说不定,哪天,你会发现某个网站上的计数器和自己的一模一样。网页越做越老练。网页上的东西,也越来越多,越来越丰富。
  
  设问:
  在网页上,如果我要添加一个计数器:
  以前,那就去空间提供商那里要个链接,或其他地方去复制个地址,但这一些,总归是别人做的,好不好,你是没有太多的发言权的,只能一个一个地找。
  在网页上,我要将一些信息发布出去:
  假如信息是文本,做一个新页面,加个链接;
  是数据,做一个新页面,加个链接:
  可要是这些数据经常更新,甚至,每小时、每分钟,都可能会改变,你是否愿意守在电脑前,不停修改、上传呢?(咱可不是商业网站,没有人愿意为你而烧钱。)
  而留言板、聊天室、论坛,这些,决不是单靠HTML和Javascript就能搞定的。
  为了实现更多的自动控制,可以使用CGI(Common Gateway Interface)程序来实现这些功能。
  
  软件需求:
  PHP:GD Library
  配置支持PHP的服务器。我用OmniHTTPd Professional
  
  对于计数器和实时数据统计、发布,我们可以用图片来完成。在图片中输出文字。
  在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)处显示一个白色的点,那么,只需如下代码:
  
  
     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表示,那么,这八行图形的代码分别是:
    
  
  要输出这些点的话,就需要先画第一行,然后第二行、第三行……到最后一行。
  用一个循环:
   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);
  }
  
  开始编程吧!
 
推荐阅读
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • Vue 2 中解决页面刷新和按钮跳转导致导航栏样式失效的问题
    本文介绍了如何通过配置路由的 meta 字段,确保 Vue 2 项目中的导航栏在页面刷新或内部按钮跳转时,始终保持正确的 active 样式。具体实现方法包括设置路由的 meta 属性,并在 HTML 模板中动态绑定类名。 ... [详细]
  • 本文探讨了如何通过最小生成树(MST)来计算严格次小生成树。在处理过程中,需特别注意所有边权重相等的情况,以避免错误。我们首先构建最小生成树,然后枚举每条非树边,检查其是否能形成更优的次小生成树。 ... [详细]
  • QUIC协议:快速UDP互联网连接
    QUIC(Quick UDP Internet Connections)是谷歌开发的一种旨在提高网络性能和安全性的传输层协议。它基于UDP,并结合了TLS级别的安全性,提供了更高效、更可靠的互联网通信方式。 ... [详细]
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 2023 ARM嵌入式系统全国技术巡讲旨在分享ARM公司在半导体知识产权(IP)领域的最新进展。作为全球领先的IP提供商,ARM在嵌入式处理器市场占据主导地位,其产品广泛应用于90%以上的嵌入式设备中。此次巡讲将邀请来自ARM、飞思卡尔以及华清远见教育集团的行业专家,共同探讨当前嵌入式系统的前沿技术和应用。 ... [详细]
  • 国内BI工具迎战国际巨头Tableau,稳步崛起
    尽管商业智能(BI)工具在中国的普及程度尚不及国际市场,但近年来,随着本土企业的持续创新和市场推广,国内主流BI工具正逐渐崭露头角。面对国际品牌如Tableau的强大竞争,国内BI工具通过不断优化产品和技术,赢得了越来越多用户的认可。 ... [详细]
  • 深入理解 Oracle 存储函数:计算员工年收入
    本文介绍如何使用 Oracle 存储函数查询特定员工的年收入。我们将详细解释存储函数的创建过程,并提供完整的代码示例。 ... [详细]
  • 本文总结了2018年的关键成就,包括职业变动、购车、考取驾照等重要事件,并分享了读书、工作、家庭和朋友方面的感悟。同时,展望2019年,制定了健康、软实力提升和技术学习的具体目标。 ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • CSS 布局:液态三栏混合宽度布局
    本文介绍了如何使用 CSS 实现液态的三栏布局,其中各栏具有不同的宽度设置。通过调整容器和内容区域的属性,可以实现灵活且响应式的网页设计。 ... [详细]
  • Linux 系统启动故障排除指南:MBR 和 GRUB 问题
    本文详细介绍了 Linux 系统启动过程中常见的 MBR 扇区和 GRUB 引导程序故障及其解决方案,涵盖从备份、模拟故障到恢复的具体步骤。 ... [详细]
  • 本文介绍了如何使用jQuery根据元素的类型(如复选框)和标签名(如段落)来获取DOM对象。这有助于更高效地操作网页中的特定元素。 ... [详细]
  • 如何配置Unturned服务器及其消息设置
    本文详细介绍了Unturned服务器的配置方法和消息设置技巧,帮助用户了解并优化服务器管理。同时,提供了关于云服务资源操作记录、远程登录设置以及文件传输的相关补充信息。 ... [详细]
author-avatar
keyu5182702936453
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有