<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
    太厲害了,不過我絕對不用  回復  更多評論
      


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


    網站導航:
     
    主站蜘蛛池模板: 亚洲伊人色欲综合网| 亚洲第一区视频在线观看| 一个人看的免费视频www在线高清动漫| 国产成人啪精品视频免费网| 国产亚洲精品第一综合| 亚洲美女在线国产| 免费观看91视频| 亚洲毛片一级带毛片基地| 99久久久精品免费观看国产| 亚洲一卡2卡三卡4卡无卡下载| 免费看a级黄色片| 九九免费精品视频在这里| 亚洲午夜未满十八勿入网站2| 无码人妻一区二区三区免费n鬼沢| 亚洲视频一区在线播放| 成人免费无码大片a毛片| 又硬又粗又长又爽免费看 | 日本亚洲免费无线码| 亚洲性无码AV中文字幕| 亚洲性在线看高清h片| 国产精品白浆在线观看免费| 国产成人精品日本亚洲专| 免费在线视频一区| 99ee6热久久免费精品6| 亚洲精品国产suv一区88| 久久乐国产精品亚洲综合| 69免费视频大片| 青草青草视频2免费观看| 亚洲国产精品无码成人片久久| 中文字幕免费在线看线人| 亚洲AV成人精品日韩一区| 亚洲日韩国产精品第一页一区| 日本zzzzwww大片免费| 一级特黄aaa大片免费看| 亚洲伊人久久大香线蕉在观 | 男人扒开添女人下部免费视频| 亚洲av无码成h人动漫无遮挡| 国产精品久久久久久久久久免费 | 成人免费视频国产| 无码人妻AV免费一区二区三区| 亚洲AV综合永久无码精品天堂|