Evgenii Goryaev aka floor12
Development of complicated web projects.

Creating a PHP library for OpenGraph images with an article title

Обложка для статьи Creating a PHP library for OpenGraph images with an article title

Recently, often and often I notice a tendency to put a news or article title on images used in the og:image or twitter:image meta tag. I decided to write a small but flexible library for these purposes.

On such images, the text is usually written in a larger font than the text surrounding this image. This allows you to attract the attention of the reader to the title of the publication, which was shared on Facebook, Twitter or another place that supports opengraph tags.

Here is an example of such an image taken this morning from Twitter:

Example of og image

And so it looks in a social network:

Example of og image

I have several projects supporting this feature that would be very useful. Therefore, I decided to write a universal library that has no external dependencies (except for the library for working with PHP-GD graphics, of course) and can fully cover the needs of my clients.

So, I got the following list of parameters that need to be configured:

  • background image;
  • text that is overlaid on top of the image;
  • font (in TTF format);
  • the position of the text in the image along the X and Y axis;
  • font size, font color, and line spacing.

I decided to set the text position, font size and line spacing as a percentage of the image width and height, this will allow the text to be placed approximately in the same place on images of different sizes - which theoretically may be needed. Also, in my opinion, the library should correctly handle the “prepositions” at the end of the line, transferring them to the next line, if possible.

As a result of pondering and studying the issue, I came to the conclusion that the most appropriate approach would be to organize the following API:

  • the path to the background image on which the text will be superimposed must be passed to the class constructor;
  • using the setters to set the other parameters;
  • pass a path to the resulting image as a parameter of generate() method.

Why does the image need to be set in the class constructor, and not with the help of setters? This is due to the fact that to set the font color, you must work with an instance of the Resource object of the GD library, that is, the image must already be read. Or, you need to do an additional check in the setter of the text color for the presence of a read image, which looks somewhat more ugly.

Theoretically, one could set all the parameters through the constructor of the class, but considering their number, one would have to use an array so as not to make a huge number of input parameters in the constructor. And then parsing an array of parameters at this stage seemed to me to be an overhead (although there is a possibility, I’ll add this method to immediately set all the library operation parameters - this option will be somewhat more compact and elegant).

The result is a good solution that works like this:

use floor12\imagenator\Imagenator;

$imagenator = new Imagenator('/path/to/image.png');     // Create object and pass the file path to class constructor;
$imagenator
   ->setColor('FF04AB')                    // Font color in HEX format;
    ->setFont('/fonts/SomeFont.ttf')        // Path to custom font;
    ->setFontSize(3)                        // Font size in percent of image height;
    ->setPadding(5)                         // Horizontal padding in percent of image width;
    ->setMarginTopInPercents(50)            // Margin from top image edge in percent of image height;
    ->setRowHeight(7)                       // Row height in percent of image height;
    ->setText('This is an article title.'); // Text to put over the image;
    ->generate('/path/to/save.png');        // Save result image as PNG

As a result, we can generate images of approximately the following contents:

Example of result image

Example of result image

Example of result image

You can find this library on my github.