使用PHP函数imagettftext()编写带表情符号的文本

7

我将使用imagettftext函数在图片上写入文本,但我的文本中包含表情符号,它会将表情符号替换为方框。

这是我的代码:

$black = imagecolorallocate ( $main_img, 0x00, 0x00, 0x00 );
$font_path = "Arial.ttf";
imagettftext ( $main_img, 14, 0, 73, 685, $black, $font_path, $text );

Text Sample:

test testt Hello  Those   Mega x ❤️  Graphic 

我尝试更改字体为“Arial Unicode”,但仍无法解决问题。请问有什么方法可以解决这个问题吗?谢谢。

你是否检查过你尝试使用的字体是否具有你要打印的Unicode范围的字符? - Markus Müller
是的,字体支持Unicode范围,但不确定是否支持表情符号。 - Bhumi Shah
需要使用表情符号库或其他什么来显示吗? - Bhumi Shah
@MarkusMüller:你有没有推荐支持表情符号测试的字体? - Bhumi Shah
5个回答

5
首先,我们需要了解表情符号是如何实现的: 苹果的PNG图像(SBIX表)

苹果使用了一种专有的、未公开的TrueType/OpenType规范扩展来将PNG图像添加到字体中。这些PNG图像随后在文本中显示。Google也实现了类似的功能,但与苹果的解决方案不兼容。

Mozilla和Adobe的SVG(SVG表)

这两个网络巨头联手打造了最雄心勃勃的格式:OpenType中的SVG。我们不是将Unicode字符映射为字形,而是将其映射为SVG图像。这给我们带来了所有可爱的额外功能,包括渐变、嵌入式位图图像甚至动画。它已经在Firefox 26版本中得到支持!

Microsoft COLR/CPAL

默认情况下,新的Segoe UI Emoji字体的行为类似于常规的TrueType/OpenType字体。它具有Unicode编码的未着色“基本字形”。但字体中还有两个附加表:COLR表将附加字形链接为基本字形的层,并定义这些层的顺序。而CPAL(“颜色调色板”)表为各个层存储一个或多个颜色调色板。(不同的颜色调色板对于在深色和浅色背景上显示字体非常有用。)因此,当支持这种新的颜色功能时,基本字形将被着色层替换。

Google的PNG图像(CBDT/CBLC表)

Google提出了一种实现方案,使用PNG图像作为字形。字形被简单地替换为老式图片。这对于较小的图标效果很好,并且显然带来所有位图图像的创意自由,但不太适合扩大。将字形放大到足够大,就会遇到模糊的像素。而使用CSS更改字形的颜色也将变得困难,甚至不可能。有趣的是,他们指定在他们的实现中不应该有GLYF表——保存未着色的“普通”字形的表——因此看起来在不支持此格式时没有后备方案。它已经在FreeType中实现,FreeType在Android和Linux上使用,但OpenType的提案将把它带到Windows和苹果机器上。


来源:12

我们感兴趣的是最后一种方法。这是因为imagefttext是PHP GD扩展提供的功能。GD内部使用FreeType库来绘制文本。
自版本2.5以来,FreeType支持表情符号。尝试执行php -i命令以查看您拥有哪个版本的FreeType。这是我的:
FreeType Support => enabled
FreeType Linkage => with freetype
FreeType Version => 2.5.2
然而,在尝试一些示例字体后,我发现这里,PHP不断抛出警告:
Warning: imagefttext(): Could not set character size

我担心GD库不支持FT_LOAD_COLOR标志。这个标志是必需的,以获得彩色表情符号。请参阅FreeType更改日志:
2013-05-23  Behdad Esfahbod
添加对颜色嵌入位图(例如彩色表情符号)的支持。
一个新的加载标志,FT_LOAD_COLOR,使FreeType加载颜色 嵌入位图,遵循此草案规范
https://color-emoji.googlecode.com/git/specification/v1.html
回答你的问题:你不能使用imagefttext来获得彩色笑脸。对不起。

编辑:

你也不能在GD中绘制黑白表情符号。这是因为GD仅支持1-3个多字节UTF-8字符。表情符号字符属于4字节UTF-8字符范围。
来源:https://github.com/libgd/libgd/blob/master/src/gdft.c#L341

带有多字节UTF-8表示的表情符号表格: http://apps.timwhitlock.info/emoji/tables/unicode


我不想使用彩色笑脸,但是我能显示笑脸而不是空心方块吗? - Bhumi Shah
@BhumiShah,我编辑了我的回答。在GD库被修复之前,这也是不可能的。 - stil
使用Imagick而不是GD函数获取表情符号是否可行? - Bhumi Shah

2

我建议您使用PHP ImageMagick库。虽然我没有尝试过使用表情符号,但在尝试使用DG渲染文本时,我遇到了与您相同的问题,即在其他Unicode字符上。

顺便说一句,迁移到IM至少是个好主意,因为它具有更好的性能和更少的缺陷。

这里有一个应该适用于您的示例


1

尝试使用已知表情符号Unicode字符的字体,比如Symbola


你能提供你尝试绘制的字符串吗? - Tomasz Tybulewicz
我一直在测试Symbola字体,有些字符可以正常显示,比如☕,但有些则不行。我认为这只是一个试错的过程,需要找到支持所需字符的字体。 - Tomasz Tybulewicz
我已经在上面添加了示例文本。另外,您能否为我提供演示? - Bhumi Shah

1
你能发布一下你想使用的表情符号吗?最好能给我们提供在选择表情后在Windows字符映射中看到的代码。 在Arial字体中,我只找到了这些表情符号:☺☻☼♀♂♠♣♥♦♪♫♯ - 它们都能正常显示。我使用了php.net上的示例。

我正在从Instagram获取数据,因此需要适用于所有表情符号的通用解决方案。您能否为我提供链接或您在php.net上尝试过的示例?您是否尝试在图像上显示这些表情符号? - Bhumi Shah
我尝试了这个例子:http://php.net/manual/en/function.imagettftext.php 但是从我看到的内容来看,我无法使用您发布的某些符号。我认为这是字体和/或编码相关的问题。 您的脚本是否以utf-8编码?PHP是否使用默认编码设置为utf-8? - kayo

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接