首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在使用imagettftext()时,如何处理字体文件不支持的字符?

在使用imagettftext()时,如何处理字体文件不支持的字符?
EN

Stack Overflow用户
提问于 2014-03-08 16:02:16
回答 4查看 3.9K关注 0票数 6

我在PHP库创建的图像中使用Verdana字体。

代码语言:javascript
运行
复制
imagettftext($image, $fontSize, 0, 70, $y, $color, $font, $username );

大多数情况下,imagettftext对于字符串非常有效。

但是我的一些用户在他们的名字里使用奇怪的字符/符号。

所以当我试图把他们的名字印到图片上时。例如:

此用户使用ɦɪɲɣƙƨєʌɾ符号。所以Verdana不能打印。

我用这个:

代码语言:javascript
运行
复制
$username=iconv('UTF-8', 'ASCII//TRANSLIT', $username);

产出如下:

(当前语言环境在英语和德语之间的变化。因此,也许当前的地区无法处理这些字符:ɦɪɲɣƙƨєʌɾ)

如果不编写一个非常大的ɦ块,似乎不可能将h音译为h,也不可能将ɲ音译为n。就像

  • 所以我想知道是否可以检查字体(Verdana)是否能显示这些符号。如果其中一个字符不能在字符串中显示,那么我可以将一个空字符串传递给imagettftext方法。我可以检查字体内的受支持字符吗?或者创建包含Verdana支持符号的字符映射,并检查我的字符串是否包含不支持的符号? (我认为这是不可能的,因为这个问题)
  • 或者另一种解决方案,在imagettftext()中可以使用多种字体吗? 例如,先试试Verdana,如果Verdana不包括符号,使用Arial,sans,serif等等。
  • 或者其他的解决方案?

编辑:

似乎Verdana在我的文本中不支持这些unicode字符。

Verdana支持的字符:http://www.fileformat.info/info/unicode/font/verdana/grid.htm

Verdana非空间字符:http://www.fileformat.info/info/unicode/font/verdana/missing.htm

EN

回答 4

Stack Overflow用户

发布于 2014-03-11 19:50:50

我的第一个选择是切换到支持您想要处理的所有字符范围的字体。但是,不要期望任何一种字体都会实现百万左右可能的字符在UTF-8中。

现在,如果您想采用(懒惰;)音译路线,我将参考这是凯末尔·达·ğ的回答

我现在手头上没有5.4版本,所以我无法知道Transliterator的情况,但是Kemal Dağ的JTransliteration端口表现得很好:

代码语言:javascript
运行
复制
<?php
    require 'transliteration/JTransliteration.php';

    $input = 'ɦɪɲɣƙƨєʌɾ';
    echo JTransliteration::transliterate($input); // output: hIngk2ie^r

    $input = 'Хეλлఒ Wओრলद';
    echo JTransliteration::transliterate($input);

最后,如果您想检查给定的字体是否支持给定的字符,那么它会变得更加毛茸茸的。这个图书馆会帮上很多忙的。它需要>= 5.3 (名称空间的使用):

代码语言:javascript
运行
复制
<?php
    $fontFile = 'arial.ttf';
    $charToCheck = 'ɣ';

    require_once 'php-font-lib-master/src/FontLib/Autoloader.php';

    use FontLib\Font;
    use FontLib\TrueType\Collection;


    $font = Font::load($fontFile);
    if ($font instanceof Collection) {
        $font = $font->getFont(0);
    }
    $subtable = null;
    foreach($font->getData("cmap", "subtables") as $_subtable) {
        if ($_subtable["platformID"] == 3 && $_subtable["platformSpecificID"] == 1) {
            $subtable = $_subtable;
            break;
        }
    }

    if (isset($subtable["glyphIndexArray"][ord_utf8($charToCheck)])) {
        $supported = 'Supported';
    } else {
        $supported = 'Not Supported';
    }

    echo "$charToCheck is $supported by font $fontFile";


    function ord_utf8($c) {
        $b0 = ord($c[0]);
        if ( $b0 < 0x10 ) {
            return $b0;
        }
        $b1 = ord($c[1]);
        if ( $b0 < 0xE0 ) {
            return (($b0 & 0x1F) << 6) + ($b1 & 0x3F);
        }
        return (($b0 & 0x0F) << 12) + (($b1 & 0x3F) << 6) + (ord($c[2]) & 0x3F);
    }

无耻地掠夺https://github.com/PhenX/php-font-lib/blob/master/www/font_info.php和R.Hill‘s https://stackoverflow.com/a/11708867/1446005的代码

P.S.字符串"ɦɪɲɣƙƨєʌɾ“由国际音标中的字符组成。我不确定任何地区是否支持这些字符(因为没有实际的需求,因为它们没有被任何真正的人类语言所使用)。

票数 4
EN

Stack Overflow用户

发布于 2014-03-17 12:10:51

只要您使用UTF-8,就没有理由使用UTF-8真字体显示这些字母(东亚字母免责声明!)

下面是我的简单示例,使用真正的字体:

代码语言:javascript
运行
复制
// utf-8 text
$text   = 'ɦɪɲɣƙƨєʌɾ';

// if text read from a file (for example)
// and the default locale (for most of western countries)
// is ISO-8859-1, you can simly convert it to
// utf-8 using:

//$text = utf8_encode($text);

$png    = imagecreatefrompng('/tmp/sample.png');
$color  = imagecolorallocate($png, 0, 0, 0);

// True type font that support UTF-8!!!!
$font   = '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf';

imagettftext($png, 50, 0, 50, 50, $color, $font, $text);
imagepng($png, '/tmp/test.png');

其结果是:

票数 3
EN

Stack Overflow用户

发布于 2014-03-09 13:40:23

你设置了正确的地点吗?对于iconv来说可能是必要的- http://cz1.php.net/manual/en/function.iconv.php#74101

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22271634

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档