在微信H5活动页面里, 为了增强活动的表现力或视觉效果,经常会出现设计师在页面中使用特殊字体库的情况,,如果页面没有复杂的交互,直接将含有特殊字体的片段切成图片就能解决这个问题,但有些场景下是不能这样做的,比如说图片是根据用户的输入合成的,这样图片就需要动态生成。
很自然就会想到,只要在这个页面上加载相应的TTF字体库,就能随意在页面上使用这种字体,但是,汉字的数量是非常多的,字体库体积非常大,少则十几M,多至几十M,如果在一个H5页面加载这么大的文件,对于用户体验(和用户的流量套餐^_^)来说简直就是灾难,那这种情况下怎么办呢?
我后来想到的解决方案是:利用生成图片验证码的技术,将前端需要生成特殊字体的内容发送到后端,在后端读取特殊字体库并生成图片返回给前端就能解决这个问题,比如说,要将用户输入的称谓或祝福语变成某种特殊字体显示时,在前端页面留一个输入框收集内容,并且在keyup事件里将输入框的内容获取出来并发给服务端,服务端页面负责读取字体库内容,找出对应的文字并且合成图片并以二进制的格式输出,前端就使用一个标签接收输出就能在前端几乎同步地显示了,这个方案能避免前端去加载庞大的字体库,用户体验更好。
你们有其它更好的实现方案吗?欢迎留言交流..
以下附上后端的参考代码: 入口 页
$text = \tools\Tools::getChar('text');
//计算字符中出现的中英文和数字分别的数量,精确计算宽度
preg_match_all("/[0-9]{1}/", $text, $arrNum);
preg_match_all("/[a-zA-Z]{1}/", $text, $arrAl);
preg_match_all('/([\x{4e00}-\x{9fa5}]){1}/u', $text, $arrCh);
$numberCount = count($arrNum[0]);
$wordCount = count($arrAl[0]);
$chineseWordCount = count($arrCh[0]);
$othersCount = mb_strlen($text) - $numberCount - $wordCount - $chineseWordCount;
$width = ($chineseWordCount+$othersCount)*90 + ($numberCount)*48 + $wordCount*55;
$height = 130;
$top = ($chineseWordCount)*5 + $wordCount*6 + $othersCount*40;
$left = 90;
if($wordCount > 0 || $numberCount > 0){
//$left = 50;
}
$font = [
'width' => $width,
'height' => $height,
'top' => $top,
'left' => $left,
'size' => 60,
'font' => dirname(__FILE__).'/../font/fangzhenglibian1.ttf',
'text' => $text
];
$mode = \tools\Tools::getChar('mode');
switch($mode) {
case 1:
$font['color'] = [51, 51, 51];
break;
case 2:
$font['color'] = [248, 225, 155];
break;
case 3:
$font['color'] = [51, 51, 51];
$font['width'] = $width;
break;
}
\tools\Tools::getTextImg($font);
生成图片的方法
/**
* 根据文字打印图片
* @param $font 要生成特殊字体图片的文本
* @param $zoom 放大倍数
*/
public static function getTextImg($font, $zoom = 1) {
header('Content-Type: image/png');
$im = imagecreatetruecolor($font['width'] * $zoom, (isset($font['height'])?$font['height']:30) * $zoom);
$transparent = imagecolorallocatealpha($im, 255, 255, 255, 127);
imagecolortransparent($im, $transparent);
imagesavealpha($im, true);
$black = imagecolorallocate($im, $font['color'][0], $font['color'][1],$font['color'][2]);
imagefill($im, 0, 0, $transparent);
imagettftext($im, $font['size'] * $zoom, 0, $font['top'] * $zoom, $font['left'] * $zoom, $black, $font['font'], $font['text']);
$arr = ['祝您:', '愿你:'];
$font['text'] = str_replace($arr, "", $font['text']);
$arr1 = ['请接受', '新春的祝愿,'];
$font['text'] = str_replace($arr1, "\t\t\t", $font['text']);
imagettftext($im, $font['size'] * $zoom, 0, ($font['top'] * $zoom)+3, $font['left'] * $zoom, $black, $font['font'], $font['text']);
imagepng($im);
imagedestroy($im);
}