计算文字在HTML中的显示宽度
2009-11-15 14:11
351 查看
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等都适用。本文出自 “CowNew开源团队” 博客,请务必保留此出处http://cownew.blog.51cto.com/413531/227465
最理想的实现方式是使用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等都适用。本文出自 “CowNew开源团队” 博客,请务必保留此出处http://cownew.blog.51cto.com/413531/227465
相关文章推荐
- html使用display:inline-block实现标签右对齐,值左对齐效果。和设置div宽度,并居中显示。嵌套div的里层div文字居中显示
- html文字超越宽度显示省略号
- HTML学习笔记——文字超出宽度显示用省略号表示
- 计算文字在固定宽度下 折行显示后的高度
- 计算文字的高度和宽度--以微博会话界面中用户名(userName)为例
- html用title属性实现鼠标悬停显示文字
- TextView通过Html,实现一行文字,颜色不同等显示
- 让SharePoint计算字段显示Html
- css固定宽度超出文字自动省略号显示
- Android计算字符串显示宽度
- text-overflow实现文字超出宽度,溢出后自动显示为省略号的效果
- iOS开发之计算文字宽度
- HTML基础 img标签设置显示图片的宽度与高度
- HTML中Input输入框的只能输入数字,限制长度,默认显示文字等
- 用css实现文字超出指定宽度显示省略号(...)
- html 竖列显示文字让文字竖列显示
- html中图片和文字显示在一行,并且交叉显示的style设置
- 两个不同宽度的view居中显示计算
- [积累]使用Html设置Textview文字显示的不同格式