Introduction
Mixer is a fully namespaced PHP class (built on top of great Imagine library) which eases the task of mixing images and text together. It offers pre-defined objects with display properties that can be set using syntax similar to CSS. The class nicely abstracts positioning and text handling nuances which you might stumbled upon while working with raw GD or Imagick functions. It can be used to generate all kinds of memes or motivation images for instance :P
Requirements:
- PHP 5.4 or above
- GD library or Imagick extension (the latter is recommended for better results)
- Imagine library
Image object
Object supports following properties:
width
height
padding
background
To construct Image object, you pass image file as an constructor argument and optionally an array of properties:
use Mixer\Shape\Image; $i = new Image('img' . DIRECTORY_SEPARATOR . 'lima.portrait.5.jpg', array( 'padding' => 20, )); $i->show(); // will set appropriate headers and send an image to the browser
When you do not specify width
and height
,
default image dimensions will be used. When you do, image will
be zoom-cropped (towards center) to match provided dimensions:
use Mixer\Shape\Image; $i = new Image('img' . DIRECTORY_SEPARATOR . 'lima.portrait.4.jpg', array( 'padding' => 10, 'width' => 100, 'height' => 100, ));
When you specify only one dimension, other will be calculated proportionally.
Text object
Object supports following properties:
width
height
padding
background
color
font
size
align
valign
outline
To construct Text object, you pass text string as an constructor argument, FontStore instance and optionally an array of properties:
use Mixer\Shape\Text; $t = new Text('Lorem Ipsum', $fontStore, array( 'font' => 'times', 'color' => '#000', 'background' => '#fff', 'padding' => 20, )); $t->show();
Note that if you do not set font
property, it will be randomly picked from passed FontStore object.
Here are some examples how text can be aligned horizontally and vertically:
If you supply both width
and height
font size
will be decreased automatically in order to fit text into resulting bounding box (if neccessary):
You can enable text outline by passing outline
property like in the following example (integer defines
outline width):
use Mixer\Shape\Text; $t = new Text('Lorem Ipsum', $fontStore, array( 'font' => 'impact', 'color' => '#fff', 'background' => '#fff', 'padding' => 20, 'size' => 36, 'outline' => '4 #000', )); $t->show();
To manually enforce new line just insert new line character \n
in passed text:
use Mixer\Shape\Text; $t = new Text("First line\nSecond line", $fontStore);
Composition object
Object supports following properties:
padding
background
Composition object allows to easily mix together Image objects, Text objects and other Composition objects. Every composition needs initial element which is passed as first constructor argument, followed by an array of properties:
use Mixer\Shape\Image; use Mixer\Shape\Composition; // let's setup some composition elements $i1 = new Image('img' . DIRECTORY_SEPARATOR . 'lima.landscape.1.jpg', array( 'width' => 300, 'padding' => 10, 'background' => '#fff', )); $i2 = new Image('img' . DIRECTORY_SEPARATOR . 'lima.landscape.2.jpg', array( 'padding' => 10, 'background' => '#999', )); $i3 = new Image('img' . DIRECTORY_SEPARATOR . 'lima.portrait.3.jpg', array( 'padding' => 10, 'background' => '#ccc', )); // let's create composition and paste elements $c = new Composition($i1, array( 'padding' => 20, )); $c->paste($i2, 'bottom'); $c->paste($i3, 'right'); $c->show();
When you paste new element into the composition, it will be resized proportionally (by default)
to fit respective side (top, bottom, left, right). You can always disable proportional resizing by
passing false
as a third param to Composition::paste()
method.
Pasting Text objects
There is one thing to remember when pasting Text objects. Let's create sample Text object:
$t = new Text("Adriana Lima is a Brazilian model and actress", $fontStore, array( 'font' => 'novecentowide', 'padding' => 20, ));
Now, let's create new composition by taking some portrait-oriented photo as initial element and pasting our Text object below the photo:
$c = new Composition(new Image('img' . DIRECTORY_SEPARATOR . 'lima.portrait.5.jpg')); $c->paste($t, 'bottom');
During the paste, Text object bounding box's width and height was scaled
proportionally to fit photo's width. That's why resulting font size
was automatically reduced in order to fit the text into new bounding box.
That is not intended behavior in some cases. If we would like to keep
our original font size we have to let Text object "grow" to the new width by using
resetHeight()
method before pasting and passing false
to disable
proportional resizing:
$c = new Composition(new Image('img' . DIRECTORY_SEPARATOR . 'lima.portrait.5.jpg')); $t->resetHeight(); $c->paste($t, 'bottom', false);
Resizing
You can resize any object using setWidth()
and setHeight()
methods. Note that
if object has not been rendered object's padding will not change after resize:
$i = new Image('img' . DIRECTORY_SEPARATOR . 'lima.portrait.1.jpg', array( 'width' => 300, 'padding' => 20, )); // Picture on the left $i->show(); // Picture in the middle $i->setWidth(150, true); $i->show(); // Picture on the right $i->render(); $i->setWidth(150, true); $i->show();
Engines
By default, Mixer will use Imagick if available. However, you can enforce your preferred engine globally using following construct before creating any object:
use Mixer\Engine; Engine::setDefault(Engine::ENGINE_GD); // or Engine::ENGINE_IMAGICK
You can also enforce engine per object basis:
use Mixer\Engine; use Mixer\Image; $i1 = new Image('img' . DIRECTORY_SEPARATOR . 'lima.portrait.1.jpg', array( 'engine' => Engine::factory(Engine::ENGINE_GD), ));
Remember though that you can only mix objects created using the same engine!
FontStore object
FontStore holds any font that you may use when creating Text objects and allows you to easily alias given font with short and friendly name. In order to create any Text object, you must instantiate FontStore object first and pass it as an argument to each Text object constructor function. When creating FontStore object, you pass filesystem path to the directory where font files (.ttf, .otf) are placed. After that you can perform aliasing:
use Mixer\FontStore; $fontStore = new FontStore(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'fonts'); $fontStore->add('times', 'times.ttf'); $fontStore->add('arial', 'arial.ttf'); $fontStore->add('novecentowide', 'Novecentowide-Bold.otf');
ImageColor object
Utility class which finds average color for Image, Text or Composition. Simply pass appropriate object as constructor argument:
use Mixer\ImageColor; $imageColor = new ImageColor(new Image('img' . DIRECTORY_SEPARATOR . 'lima.portrait.5.jpg')); $averageColor = $imageColor->getAverageColor(); // $averageColor is now a Imagine's Color object echo $averageColor; // which outputs hex code (ie. #a1866d) while casting to string echo $averageColor->getValue('red'); // but also has some nice helper methods $averageColor2 = $imageColor->getAverageColorByResize(); // alternative average color sampling algorithm
ImageColor class has also handy static method getContrastColor()
which finds optimal text color (white or black) for given background color:
use Mixer\ImageColor; echo ImageColor::getContrastColor('#000') // returns #ffffff
Methods
name | object | description |
---|---|---|
getWidth($inner = false) |
Image, Text, Composition | Returns object width (with padding). Pass true to get object inner width (without padding).
|
getHeight($inner = false) |
Image, Text, Composition | Returns object height (with padding). Pass true to get object inner height (without padding).
|
setWidth($newWidth, $proportional = false) |
Image, Text, Composition | Sets object new width. If you pass true as second param, height will be adjusted proportionally
to the new width.
|
setHeight($newHeight, $proportional = false) |
Image, Text, Composition | Sets object new height. If you pass true as second param, width will be adjusted proportionally
to the new height.
|
show($format = 'jpg') |
Image, Text, Composition | Renders object (if not already rendered), sets appropriate headers and sends an image to the browser. Allows to pass in output format. |
save($file, $options = []) |
Image, Text, Composition |
Saves object to file. Pass in filename with correct extension (either .jpg, .png or .gif).
You can specify $options in order to set quality of saved images:$options['jpeg_quality'] (from 0 to 100)$options['png_compression_level'] (from 0 to 9) |
render() |
Image, Text, Composition | Renders object into Imagine handle. |
getHandle() |
Image, Text, Composition | Returns Imagine handle (if null you
need to call render() before).
|
paste($object, $position, $proportional = true) |
Composition |
Pastes new object into the composition. Pass 'top' , 'bottom' ,
'right' , 'left' as $position param.
|
pasteInside($object, $position) |
Composition |
Pastes new object inside the composition. Pass an array with x and y as $position
param.You can pass integers: array(10, 10) .Alternatively you can pass position keywords (the same as when using CSS background-position): array('center',
'center') .
|
Properties
name | object | default value | type | description |
---|---|---|---|---|
width |
Image, Text | not set | integer | Pass integer to set total object width (with padding). |
height |
Image, Text | not set | integer | Pass integer to set total object height (with padding). |
padding |
Image, Text, Composition | 0 |
integer/string |
Pass integer to set equal padding on each side or alternatively you can pass string similar to CSS shorthand: '20 10' or '20
5 10 30' .
|
background |
Image, Text, Composition | '#000' |
string |
To set background color, pass hex color string: '#fc0' .To create linear gradient, pass two colors separated by whitespace: '#fc0 #f00' .You can alter opacity of each color by appending comma and value (0-100) after hex color in following way: '#fc0,80' .
|
color |
Text | '#fff' |
string |
Defines text color. Pass hex color string: '#fc0' .Optionally you can include opacity modifier after comma, see background property above.
|
font |
Text | not set |
string | Defines text font. Pass friendly font name (alias) that you have defined inside FontStore instance. |
size |
Text | 16 |
integer | Defines text font size in points. |
align |
Text | 'left' |
string |
Defines text align. Available values: 'left' , 'center' or 'right' .
|
valign |
Text | 'top' |
string |
Defines text vertical align. Available values: 'top' , 'middle' or
'bottom' .
|
outline |
Text | '0 #000' |
string/integer |
Defines text outline. Pass integer to set outline width only. Pass string with outline width and color to
set both: '5 #fc0' (order does not matter).
|
Download
At the moment the class is not open-source. If you would like to use it in your project - write me an e-mail describing general details. I may send you zipped archive (together with MotivationImage class) for free or ask for small donation via PayPal or Bitcoin to support project development.