Blog

Where we discuss our work, thoughts, and process

Add text to an image with PHP

We released an open source PHP library this week. It's called Image with Text and, true to its name, it makes it super easy for you to add text to images with PHP.

Why?

It's not often we need to add text to an image, but occasionally a client approaches us with a project idea that requires it. For example, we recently built an application that lets friends and family deliver customized e-cards to hospital patients. Each card can be customized with a title, a message, and the name of the sender. The customized card is generated with our Image with Text library, then emailed either to the patient or the nurses desk for printing and hand-delivery.

And memes. Those, too!

Typography

Our Image with Text PHP library allows you to add styled text to an image. You can control each text block's typography, including:

  • Alignment
  • Color
  • Line Height
  • Size

You can use custom fonts, too! Just download a TTF or OTF font (appropriately licensed, of course) and then set the text block's font property to the relative or absolute path of the font file. Both Google Fonts and TypeKit are great places to find fonts.

Each text block is assigned exact coordinates to position it on top of the source image. If the text is left or center aligned, the X and Y coordinates are relative to the top left of the source image; if the text is right aligned, the X and Y coordinates are relative to the top right of the source image.

Flow Control

A text block is assigned a maximum character width and a maximum number of lines. The character width controls when the text block's text will break to a new line. If the text exceeds the available lines, an exception is thrown. You define the maximum number of lines and maximum number of characters per line when you create a text block, like this:

<?php
$text = new \NMC\ImageWithText\Text('Your text', 3, 25);

The second argument is the maximum number of lines, and the third argument is the maximum number of characters per line. Both of these are optional, and they default to 1 line and 80 characters, respectively.

Example

Here's a working example that puts everything together! You'll see that we create an image, add two blocks of text to the image, and render the image with text to a new file on disk.

<?php
// Enable Composer autoloading
require '../vendor/autoload.php';

// Create image
$image = new \NMC\ImageWithText\Image('source.jpg');

// Add text to image
$text1 = new \NMC\ImageWithText\Text('Thanks for using our image text PHP library!', 3, 25);
$text1->align = 'left';
$text1->color = 'FFFFFF';
$text1->font = 'fonts/Ubuntu-Medium.ttf';
$text1->lineHeight = 36;
$text1->size = 24;
$text1->startX = 40;
$text1->startY = 40;
$image->addText($text1);

// Add more text to image
$text2 = new \NMC\ImageWithText\Text('No, really, thanks!', 1, 30);
$text2->align = 'left';
$text2->color = '000000';
$text2->font = 'fonts/Ubuntu-Medium.ttf';
$text2->lineHeight = 20;
$text2->size = 14;
$text2->startX = 40;
$text2->startY = 140;
$image->addText($text2);

// Render image
$image->render('destination.jpg');

This code will produce this image:

Example image generated with our PHP library

Installation

We recommend you install our Image with Text PHP library with Composer. Update your project's composer.json file with:

{
    "require": {
        "nmcteam/image-with-text": "~2.0"
    }
}

Then run composer install.

Contribute

Our Image with Text PHP library is open source and released with the MIT Public License. Please helps us make it even better! You can contribute on GitHub here:

 

Comments

Thomas Rudy's avatar
Thomas Rudy
Very cool. I'll have to give this a try.
Sahil Sharma's avatar
Sahil Sharma
It's nice library, very well done with this! I've also created an article about adding text to an image in PHP I think beginners should understand how this actually works.

Great work, keep it up!

Kind Regards
Sahil Sharma
http://www.webdevelopersahil.com/
Ashish's avatar
Ashish
it is not working


there is a error fetal error ! in
$image = new \NMC\ImageWithText\Image('source.jpg');
what to do?
daniel's avatar
daniel
When using composer to install, I get this message:

Problem 1
- The requested package nmcteam/image-with-text 1.0.0 could not be found.

Hopefully that has something to do with why I get this error because I noticed another project gets this error too:

Forbidden

You don't have permission to access /image-with-text/example/demo on this server.

Apache/2.2.22 (Ubuntu) Server at localhost Port 80

Of course, this file path does not even exist, possibly due to composer not being able to install:

require '../vendor/autoload.php';

No sign of any autoload.php in the entire project folder.
Josh Lockhart's avatar
Josh Lockhart NMC team member
Just left you some feedback here:

https://github.com/nmcteam/image-with-text/issues/5
Joel Sutherland's avatar
Joel Sutherland
This is great -- I'd love to use it for a meme generator.
Mike's avatar
Mike
This looks like the best library out there. I'll give it a try and report back! Thanks Josh!
Migliorhosting.biz's avatar
Migliorhosting.biz
Super library, thanks very much.
Yavor Petrov's avatar
Yavor Petrov
Thanks for the cool library. There is a small bug when center aligning a text with new rows (enter), coming from textarea. The text after the new row (enter) is positioned to the left and not centered. Otherwise good job.
Yavor Petrov's avatar
Yavor Petrov
This is what I ended up with changing the distributeText method:

protected function distributeText()
{
// Explode input text on word boundaries
$words = explode(' ', $this->text);

// Fill lines with words, toss exception if exceed available lines
while ($words) {
$tooLong = true;
$word = array_shift($words);

$word_arr = explode("\r\n", $word);
$word = $word_arr[0];

for ($i = 0; $i < count($this->lines); $i ) {
$line =& $this->lines[$i];
if ($line['full'] === false) {
$charsPotential = strlen($word) $line['chars'];

if ($charsPotential <= $this->width) {
array_push($line['words'], $word);
$line['chars'] = $charsPotential;
$tooLong = false;

if(sizeof($word_arr)>1){
array_splice($word_arr, 0, 1);
$word = $word_arr[0];
$line['full'] = true;
}else{
break;
}
} else if(sizeof($word_arr)==1){
$line['full'] = true;
}
}
}
}

// Throw if too long
if ($tooLong === true) {
throw new \Exception('Text is too long');
}
}

If it helps someone else. Cheers
deerox's avatar
deerox
How to use it with out composer ? manually

Leave a comment