Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP function imagettftext() to write text with smileys

I am using imagettftext function to write text on image but my text contain smileys and it replace smileys to square box

Here is mycode:

$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 💋

I have tried with changing font which is "Arial Unicode" but its not solved issue.

How can i solve this issue?

Thanks in advance.

like image 203
Bhumi Shah Avatar asked Sep 04 '15 05:09

Bhumi Shah


2 Answers

Firstly, we need to understand how emojis are implemented:

Apple’s PNG images (SBIX table)

Apple implemented it using a proprietary, unpublished extension of the TrueType/OpenType specification to add PNG images to a font. These PNG images are then displayed within running text. Google also implemented similar thing, but it is not compatible with Apple’s solution.

Mozilla and Adobe’s SVG (SVG table).

These two web giants got together for the most ambitious format: SVG in OpenType. Instead of mapping a Unicode char to a glyph, we map it to an SVG image. This brings us all the lovely extra’s of SVG, including gradients, embedded bitmap images and even animation. It’s already been supported in Firefox since version 26!

Microsoft COLR/CPAL

By default, the new Segoe UI Emoji font behaves like a regular TrueType/OpenType font. It has Unicode-encoded, uncolored “base glyphs”. But there are two additional tables in the font: the COLR table links additional glyphs as layers to the base glyphs and defines the order of these layers. And the CPAL (“Color Palette”) table stores one or more color palettes for the individual layers. (The different color palettes are useful for displaying the font on dark and light backgrounds.) So when there is support for this new color feature, the base glyphs will be replaced with the colored layers.

Google’s PNG images (CBDT/CBLC tables).

Google proposed an implementation which uses PNG images for the glyphs. The glyphs are simply replaced by good old images. This works fine for smaller icons, and obviously brings all the creative freedom of bitmap images, but doesn’t scale very well. Blow up a glyph big enough, and you’ll encounter blurred pixels. It’s also going to be hard, if not impossible, to change the color of the glyphs with CSS. Interesting is that they specify that there should be no GLYF table in their implementation — the table that holds the uncolored “normal” glyphs — so it looks like there’s no fallback for when this format isn’t supported. It’s already implemented in FreeType, which is used on Android and Linux, but a proposal for OpenType would bring this to Windows and Apple machines as well.


Sources: 1 and 2

The last approach is what we are interested in. This is because imagefttext is function provided by PHP GD extension. And GD internally uses FreeType library to draw text.

Emojis are supported in FreeType since version 2.5. Try executing php -i command to see what version of FreeType do you have. This is mine:

FreeType Support => enabled
FreeType Linkage => with freetype
FreeType Version => 2.5.2

However, after trying with some sample fonts I found here, PHP keeps throwing warning:

Warning: imagefttext(): Could not set character size

I'm afraid that GD library doesn't support FT_LOAD_COLOR flag. This flag is required to have colored emojis. See FreeType changelog:

2013-05-23  Behdad Esfahbod  

    Add support for color embedded bitmaps (eg. color emoji).

    A new load flag, FT_LOAD_COLOR, makes FreeType load color
    embedded-bitmaps, following this draft specification

      https://color-emoji.googlecode.com/git/specification/v1.html

To answer your question: you can't have colored smileys using imagefttext. I'm sorry 😉.

Edit:

You can't also draw black and white emojis in GD. This is because GD supports only 1-3 multibyte UTF-8 characters. Emojis characters range belongs to 4 byte UTF-8 characters.

Source: https://github.com/libgd/libgd/blob/master/src/gdft.c#L341

Emojis table with multibyte UTF-8 representation: http://apps.timwhitlock.info/emoji/tables/unicode

like image 198
stil Avatar answered Nov 15 '22 00:11

stil


I suggest You using PHP ImageMagick library. Though I didn't try it with emoji I'we encountered the same problem as yours with other Unicode characters when tried to render text with DG.

BTW migrating to IM is good idea at least because of better performance and less quirks in it.

Here is an example that should work for You

like image 44
Andrew Avatar answered Nov 15 '22 01:11

Andrew