<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    如鵬網 大學生計算機學習社區

    CowNew開源團隊

    http://www.cownew.com 郵件請聯系 about521 at 163.com

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      363 隨筆 :: 2 文章 :: 808 評論 :: 0 Trackbacks

    php中可以使用strlen或者mb_strlen計算字符串的長度,但是這些長度計算的都是在計算機中表示的長度,并不是實際在屏幕上顯示的寬度。如下圖(使用的是arial字體):


    最理想的實現方式是使用imagettftext計算字符串使用特定字體顯示的寬度:
    function tf_strlen($str)
    {
     return ceil(tf_strwidth($str)/tf_strwidth('測'));
    }
    function tf_strwidth($str)
    {
     $im=imagecreatetruecolor(10,10);
     $r=imagettftext($im, 12, 0, 5, rand(14, 16),0, 'arial.ttf', $str);
     return $r[2]-$r[0];
    }

    需要在本地計算機的字體文件夾中找到'arial.ttf',然后上傳到php頁面同級的目錄下。這樣調用tf_strlen得到的就是字符串在屏幕上的顯示寬度了。但是因為imagettftext是GD級別的操作,因此效率非常低,編寫下面的程序驗證

    $begin=microtime(true);
    $im=imagecreatetruecolor(1000,1000);
    for($i=0;$i<10000;$i++)
    {
    imagettftext($im, 12, 0, 5, rand(14, 16),0, 'arial.ttf', "rupeng.com 如鵬網 在校不迷茫,畢業即輝煌");
    }
    $t1=microtime(true)-$begin;
    echo 'imagettftext:'.$t1.'<br/>';
    $begin=microtime(true);
    for($i=0;$i<10000;$i++)
    {
    strlen("rupeng.com 如鵬網 在校不迷茫,畢業即輝煌");
    }
    $t2=microtime(true)-$begin;
    echo 'strlen:'.$t2.'<br/>';

    echo $t1/$t2.'<br/>';

    運行后發現imagettftext的運行時間是strlen的4000多倍,太慢了,而且CPU占用率非常高,因此被否定。

    經過觀察發現arial字體下,漢字的寬度是一致的,而1、i、l等字符的寬度大約是漢字的0.4倍,而阿拉伯數字(除了1)的寬度則是漢字的約0.7倍,小寫字母(除了i、l等)的寬度是漢字的約0.7倍,大寫字母則是漢字的0.8倍,其他字符也可以得出相應的倍率。因此我編寫了下面程序用來計算字符串占的寬度(單位是1/2的中文寬度)。

    function arial_strlen($str)
    {
     $lencounter=0;
     for($i=0;$i<strlen($str);$i++)
     {
      $ch=$str[$i];
      if(ord($ch)>128)
      {
       $i++;
       $lencounter++;
      }
      else if($ch=='f'||$ch=='i'||$ch=='j'||$ch=='l'||$ch=='r'||$ch=='I'
      ||$ch=='t'||$ch=='1'
      ||$ch=='.'||$ch==':'||$ch==';'||$ch=='('||$ch==')'
      ||$ch=='*'||$ch=='!'||$ch=='\'')
      {
       $lencounter+=0.4;
      }
      else if($ch>='0'&&$ch<='9')
      {
       $lencounter+=0.7;
      }
      else if($ch>='a'&&$ch<='z')
      {
       $lencounter+=0.7;
      }
      else if($ch>='A'&&$ch<='Z')
      {
       $lencounter+=0.8;
      }  
      else
      {
       $lencounter++;
      }
     }
     return ceil($lencounter*2);
    }

    經過大量的測試,發現和imagettftext的運行結果非常接近,而速度則比imagettftext高很多,CPU占用率也低很多。
    解決思路對于其他語言,比如C#、Java等都適用。

    posted on 2009-11-15 14:06 CowNew開源團隊 閱讀(3916) 評論(5)  編輯  收藏

    評論

    # re: 計算文字在HTML中的顯示寬度 2009-11-15 17:54 杜國
    挺有意思的技術。

    不過這么復雜的技巧在實際應用中會很難以維護,特別對于不同瀏覽器/版本,不同字體,不同操作系統。 最好還是依賴瀏覽器自身的寬度控制width/overflow等來實現比較保險。  回復  更多評論
      

    # re: 計算文字在HTML中的顯示寬度 2009-11-15 19:59 CowNew開源團隊
    @杜國
    謝謝指教。不過像“文章列表中的標題長度不足部分用省略號,但是要盡可能用能用的空間顯示盡可能長的標題”這樣的需求怎么能滿足呢?  回復  更多評論
      

    # re: 計算文字在HTML中的顯示寬度 2009-11-16 10:07 Lancelot
    用CSS控制  回復  更多評論
      

    # re: 計算文字在HTML中的顯示寬度 2009-11-16 11:22 主任
    @Lancelot
    怎么樣用css控制字符串的長短?請指教。  回復  更多評論
      

    # re: 計算文字在HTML中的顯示寬度 2009-11-17 11:30 Ranker
    太厲害了,不過我絕對不用  回復  更多評論
      


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 国产免费av一区二区三区| 91免费国产精品| 日日AV拍夜夜添久久免费| 亚洲an日韩专区在线| 亚洲中文无码永久免费| 亚洲一区二区三区不卡在线播放 | 亚洲人成色7777在线观看不卡| 国产区图片区小说区亚洲区| 亚洲第一区精品观看| 一区二区三区免费视频网站| 亚洲精品无码不卡在线播HE | 免费中文字幕不卡视频| 一级做a爰片久久免费| 亚洲精品午夜国产VA久久成人| 99视频有精品视频免费观看| 亚洲日韩在线视频| 女性自慰aⅴ片高清免费| 久久亚洲精品高潮综合色a片| 亚洲另类激情专区小说图片| 你是我的城池营垒免费观看完整版| 亚洲av日韩av无码黑人| 中文字幕免费视频| 亚洲精品无码日韩国产不卡av| 亚洲高清视频一视频二视频三| 三年片在线观看免费西瓜视频| 亚洲精品**中文毛片| 日韩中文无码有码免费视频| 男女拍拍拍免费视频网站| 91情国产l精品国产亚洲区 | 久久国产精品免费| 亚洲欧洲精品国产区| 国产成人免费a在线视频色戒| 99精品视频在线观看免费| 亚洲Av高清一区二区三区| 免费在线观看亚洲| 日韩精品久久久久久免费| 亚洲精华液一二三产区| 亚洲AV无码一区东京热| 免费激情视频网站| 久久国产乱子免费精品| 亚洲日本VA午夜在线影院|