解决imagettftext()因为–enable-gd-jis-conv导致乱码的另一种方法

虽然 imagettftext() 文档标明只接受UTF-8编码,但如果PHP编译时启用–enable-gd-jis-conv选项的话,那么非ASCII字符(例如汉字、拼音、希腊文和箭头) 会被当成EUC-JP编码 (phpinfo中美其名曰“支持JIS编码的字体”), 从而导致乱码(由于西文字体没有假名或汉字,一般表现为全部是方框)。

Although imagettftext() documentation indicates it only accepts UTF-8 encoding, but if –enable-gd-jis-conv is specified when compiling PHP, then non-ASCII characters (like Chinese, accented characters, Greek and arrows) will be (mis-)treated as EUC-JP encoding (referred to as “JIS-mapped Japanese Font Support” in phpinfo) leading to mojibake (this usually shows up as hollow rectangles, as most fonts for western text lacks glyphs for kanji or kana).

网上大部分对此的解决方法是重新编译PHP,但是这只有自己架设服务器的时候才有用。对于付费空间 (特别是每个月不到1美元的付费空间) 就没辙了。不过imagettftext()也接受另外一种字符表示方法,类似HTML的字符参考。说“类似”是因为GD只接受数字参考,所以内部函数 (如 mb_convert_encoding) 转出来的没用。 以下的函数可以将UTF-8转换成字符参考:

A popular response online is to recompile PHP, but that only works if you’re running your own server. For paid hosting (especially paid hosting that costs less than a dollar a month) this method is kinda stumped. But imagettftext() also accepts another way for representing characters, similar to HTML’s character references. “Similar” because it only accepts numeric references, so named references converted by internal functions (likemb_convert_encoding) is of no use. The function below converts UTF-8 into character references:

//created by Kakurady
//no rights reserved
//no warranties explicit or implicit either
function to_entities($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 .= "&#xfffd";
        } 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;
}

imagettftext($im, 11, 0, 5, 11, $black, $font,  to_entities($text));
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值