工作中遇到使用GD库生成图片,在图片上写文本时,出现了乱码。
PHP GD 库 使用 imagettftext 向图像写入文本时 文本包含命名实体 (如:™™™) 如何转 UTF-8
function createImg()
{
//场景: 微信昵称带有实体命名
$nickname = 'E李 ™';
//清除缓存
ob_clean();
//一、创建画布
$xWidth = 0;
$nicknameWidth = 330;
$nicknameHeight = 56;
//指定画布尺寸
$image = imagecreatetruecolor(640, 1008);
//创建颜色 白色
$white = imagecolorallocate($image, 0, 255, 0);
//创建颜色 黑色
$black = imagecolorallocate($image, 255, 255, 255);
//自定义画布的背景颜色
imagefill($image, 0, 0, $white);
//字体
$regularFontPath = resource_path('font/SourceHanSansSC-Regular.otf');
//二、剔除文本中 emoji 标签
$nickname = removeEmojiChar($nickname);
//文本转为 utf-8
$text = toEntities($nickname, "html-entities", "utf-8");
//写入文本
imagettftext($image, $nicknameSize, 0, $xWidth, $yTextHeight, $black, $nicknameFont, $text);
//三、输出图片到浏览器
header("Content-Type: image/png");
imagepng($image);
//释放内存
imagedestroy($image);
}
//文本处理方法
function toEntities($string)
{
$len = strlen($string);
$buf = "";
for ($i = 0; $i < $len; $i++) {
if (ord($string[ $i ]) <= 127) {
$buf .= $string[ $i ];
} else if (ord($string[ $i ]) < 192) {
//unexpected 2nd, 3rd or 4th byte
$buf .= "�";
} else if (ord($string[ $i ]) < 224) {
//first byte of 2-byte seq
$buf .= sprintf("&#%d;", ((ord($string[ $i + 0 ]) & 31) << 6) + (ord($string[ $i + 1 ]) & 63));
$i += 1;
} else if (ord($string[ $i ]) < 240) {
//first byte of 3-byte seq
$buf .= sprintf("&#%d;", ((ord($string[ $i + 0 ]) & 15) << 12) + ((ord($string[ $i + 1 ]) & 63) << 6) + (ord($string[ $i + 2 ]) & 63));
$i += 2;
} else {
//first byte of 4-byte seq
$buf .= sprintf("&#%d;", ((ord($string[ $i + 0 ]) & 7) << 18) + ((ord($string[ $i + 1 ]) & 63) << 12) + ((ord($string[ $i + 2 ]) & 63) << 6) + (ord($string[ $i + 3 ]) & 63));
$i += 3;
}
}
return $buf;
}
//剔除 emoji 标签
function removeEmojiChar($str)
{
$mbLen = mb_strlen($str);
$strArr = [];
for ($i = 0; $i < $mbLen; $i++) {
$mbSubstr = mb_substr($str, $i, 1, 'utf-8');
if (strlen($mbSubstr) >= 4) {
continue;
}
$strArr[] = $mbSubstr;
}
return implode('', $strArr);
}