• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    在PHP中用描點法“繪制”中文

    發布: 2007-7-14 19:53 | 作者: 佚名    | 來源: 網絡轉載     | 查看: 8次 | 進入軟件測試論壇討論

    領測軟件測試網


    前言:
    現在,越來越多的人喜歡上網了,越來越多的人擁有了自己的個人主頁。隨著各種自動化軟件工具的出現,制作網頁越來越簡單。但,由于特效隨處可得,創新的東西,越來越少。說不定,哪天,你會發現某個網站上的計數器和自己的一模一樣。網頁越做越老練。網頁上的東西,也越來越多,越來越豐富。
    設問:

    在網頁上,如果我要添加一個計數器:
    以前,那就去空間提供商那里要個鏈接,或其他地方去復制個地址,但這一些,總歸是別人做的,好不好,你是沒有太多的發言權的,只能一個一個地找。
    在網頁上,我要將一些信息發布出去:
    假如信息是文本,做一個新頁面,加個鏈接;
    是數據,做一個新頁面,加個鏈接:
    可要是這些數據經常更新,甚至,每小時、每分鐘,都可能會改變,你是否愿意守在電腦前,不停修改、上傳呢?(咱可不是商業網站,沒有人愿意為你而燒錢。)
    而留言板、聊天室、論壇,這些,決不是單靠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);
    ?>

    對于這個函數,我們還可以進行擴充,以實現不同的效果。

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備10010545號-5
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>