My work life has been quite busy lately and I haven’t had a chance to sit down and blog. I have been touring around London and some parts of the northern England consulting and organizing some training here and there. Luckily I have had the chance to do some work on Imagick and the 2.2.0 beta release is getting closer. The internal structure was completely restructured and broken down into several smaller files. During this time Imagick was adapted to follow the PHP Coding Standards more closely. Still a work in progress
I committed slightly modified version of this example to PHP Manual http://uk.php.net/manual/en/imagick.examples.php page a few days ago. The example illustrates using an image as a part of a named fill pattern. The fill pattern is used to annotate text but the named pattern could also be used to fill any shapes that allow fill to be specified (include circles, ellipses, rectangles, polygons etc etc). The code itself is pretty straight forward: Read the image, create the pattern and use the pattern as a fill.
The ice formations image is from http://www.photoeverywhere.co.uk/west/winterholiday/slides/iceformations5679.htm.
- <?php
- /* Create a new imagick object */
- $im = new Imagick( 'iceformations5679.JPG' );
- /* Create imagickdraw object */
- $draw = new ImagickDraw();
- /* Start a new pattern called "ice" */
- $draw->pushPattern( 'ice' , 0 , 0 , 50 , 50 );
- /* Composite the image on the pattern */
- $draw->composite( Imagick::COMPOSITE_OVER, 0, 0, 50, 50, $im );
- /* Close the pattern */
- $draw->popPattern();
- /* Use the pattern called "ice" as the fill */
- $draw->setFillPatternURL( '#ice' );
- /* Set font size to 52 */
- $draw->setFontSize( 52 );
- /* Annotate some text */
- $draw->annotation( 5, 50, "Hello World!" );
- /* Create a new canvas and white image */
- $canvas = new Imagick();
- $canvas->newImage( 310, 70, "white" );
- /* Add black border around the resulting image */
- $canvas->borderImage( 'black', 1, 1 );
- /* Draw the ImagickDraw on to the canvas */
- $canvas->drawImage( $draw );
- /* Set the format to PNG */
- $canvas->setImageFormat( 'png' );
- /* Output the image */
- header( "Content-Type: image/png" );
- echo $canvas;
- ?>
And the result is here:

Pingback: Mikko Posts About Imagick in PHP and Fill Patterns - Mats Lindh
Pingback: Mikko Posts About Imagick in PHP and Fill Patterns | Mats Lindh
#1 by Fifek on May 4, 2008 - 5:08 pm
Quote
It’s not exactly concerning this topic, but do you know how to use optimizeImageLayers() function? I just can’t make it work and that makes me sick
Additionally, Mikko you make a great job with all these examples
#2 by George on May 5, 2008 - 4:12 pm
Quote
And this is exactly what I’ve been asking you about in December or so
By the way, it can also be done with a different approach but this is slightly better, using just one function…
#3 by Fifek on May 6, 2008 - 1:36 pm
Quote
What do you mean by different approach?
Can you describe it? The thing is that the command line optimization is working fine, but you have to have a way to access exec() on your server, and that’s mostly the problem ;/
#4 by Aho on May 7, 2008 - 10:16 pm
Quote
This did look really nice and I have to agree with Mats that GD suxx and I hope that Imagick would become part of the PHP in a similar way as GD is today.
Quite busy over here, just a bit over a week left on my current job and then it’s time to move and hopefully a day or two of rest before first day at my new work and hopefully a bit time over to see if I can’t manage to help this project with some new documentation.
#5 by Aho on May 7, 2008 - 10:17 pm
Quote
Forgot to mention that I liked the old design a bit more than this new one, it feels a bit “empty”, but I have to admit it’s better than what I usually make.
#6 by George on May 12, 2008 - 11:58 pm
Quote
@Fifek: the other approach i was talking about also involves Imagick and an emulation of this fill pattern by using different layers and creating a mask. It is a bit more akward but by the time i needed it Imagick didn’t have a function for pattern filling.
Also about the exec() usually it’s not about having access to it as to the time it needs to execute.
#7 by Chris on May 23, 2008 - 8:31 am
Quote
I have to say MIKKO YOU ROCK!! After searching for days and days of good examples of Imagick, I found your blog and have learned a ton since. Keep up the good work!
#8 by virus-2k on June 24, 2008 - 4:30 pm
Quote
hi.
it would be great if anyone can answer to my question here: http://valokuva.org/?p=72#comment-4087
#9 by mattia on July 7, 2008 - 11:24 am
Quote
mikko, can you suggest me an hosting with Imagick installed?
thanks
#10 by Felix on August 18, 2008 - 10:49 pm
Quote
Hey, I just installed Imagick today and did some fiddling around with it and came over your blog. Awesome! Some posts were really helpful and relevant to my interests.
. Why I’m doing this is because Imagick can use SVG images.
I have a question though, maybe a tut on this? I’m trying to rewrite my website to use Imagick (the website itself is pretty crappy, but the functionality is awesome
If you don’t have time to visit my website, here’s what it basically does: takes some text, prints it to an image and makes it public. This is currently done using GD2. Why I want Imagick is for the background of that image, which currently is a rounded rectangle (no antialias) done with GD2. That’s pretty simplistic. I was thinking I can make a few SVG “themes” which would be opened by Imagick, sized to the right size to fit the text (that’s why I don’t use some static PNG — SVGs can be resized to any size), print the text, save the image as bitmap (PNG most probably).
Now, my problem is with resizing the SVG. I can easily determine the size it *needs* to be, using the queryFontMetrics you showed me ^.^, but I don’t know how to resize the SVG to that size.
If I use thumbnailImage(), it doesn’t resize the SVG as a vector-graphics image, but as a bitmap.
If I use setResolution(), it resizes the SVG in inches, or something, because if I use, for example, setResolution(300, 200), it actually creates a 1250×555 pixels image, instead of a 300×200. How can I achieve a 300×200 pixels image? Please help me
I hope I made myself clear, and thanks again for all your examples!
#11 by Mikko Koppanen on August 19, 2008 - 12:01 am
Quote
Felix,
try using Imagick::setImageUnits / getImageUnits
#12 by Felix on August 19, 2008 - 3:46 am
Quote
Hi,
Thanks a lot for your response! But, getImageUnits() returns 0 and setImageUnits() doesn’t seem to do anything no matter what I pass to it. Here’s a bit of my code:
$im = new Imagick();
$im->setResolution(300, 200); // boasts the image up to 1250×555
$im->readImage(“s2w1.svg”);
$im->getImageUnits(); // returns 0
$im->setImageUnits(1000); // does nothing no matter what argument i give it
$im->setImageFormat(“png”); // convert resized SVG to PNG
header(“Content-Type: image/png”); // send corresponding header
echo $im; // send PNG
I’m using imagick 2.2.0 and ImageMagick 6.3.7 02/19/08
Maybe I’m missing something
? Thanks again
#13 by Felix on August 19, 2008 - 3:56 am
Quote
I left another comment but it didn’t appear. The last one appeared instantly, so I’m posting this one again. Please feel free to delete it if it’s a duplicate.
Thanks for your reply
, but I don’t actually know how to use those functions. They’re not documented in the php manual and besides that, getImageUnits always returns 0 and setImageUnits has no effect whatsoever. Here’s a bit of my code:
$im = new Imagick();
$im->setResolution(300, 200); // boasts the image to 1250×555
$im->readImage(“s2w1.svg”);
$im->getImageUnits(); // returns 0
$im->setImageUnits(1000); // has no effect
$im->setImageFormat(“png”); // convert to PNG
header(“Content-Type: image/png”);
echo $im; // output the resized SVG as PNG
Using Imagick 2.2.0 and ImageMagick 6.3.7 02/19/08 Q16.
Maybe I’m missing something
? Thanks again for the reply
#14 by Mikko Koppanen on August 19, 2008 - 11:37 am
Quote
Felix,
try giving one of the Resolution constants from http://uk2.php.net/manual/en/imagick.constants.php
#15 by Felix on August 19, 2008 - 12:57 pm
Quote
Should I use those constants in the setImageUnits function call? If yes, it still doesn’t do anything, no matter which one of those constants I use
.
#16 by Mikko Koppanen on August 19, 2008 - 1:05 pm
Quote
Felix,
seems to be working just fine here:
identify TEST.svg
TEST.svg SVG 279×279 279×279+0+0 16-bit DirectClass 7.1e+02b 0.250u 0:04
< ?php
$im = new imagick("TEST.svg");
$im->thumbnailImage(100, 100);
$im->writeImage(“processed.png”);
?>
identify processed.png
processed.png PNG 100×100 100×100+0+0 16-bit DirectClass 13.3kb
#17 by Felix on August 19, 2008 - 1:51 pm
Quote
I know about thumbnailImage, but as I said, it resizes the SVG as a bitmap, not as a vector graphics image. I’ll demonstrate:
$ identify s2w1.svg
s2w1.svg SVG 300×200 300×200+0+0 DirectClass 16-bit 1.23438kb
(the SVG is a simple black rectangle with rounded corners)
Now, I used setResolution(300, 200) and thumbnailImage(1250, 555) in order to achieve images of the same size (they’re both 1250×555). Here are the outputs:
. Thanks a lot for your help
setResolution: http://i80.photobucket.com/albums/j161/znupi/imagick/setResolution.png
thumbnailImage: http://i80.photobucket.com/albums/j161/znupi/imagick/thumbnailImage.png
As you can see, the quality of the image resulted using thumbnailImage is a lot poorer, because it treats the SVG as a bitmap (yes, I do make the thumbnailImage function call *before* converting to PNG). setResolution doesn’t treat it as a bitmap, but as a vector-graphics image, which makes the resulting image a lot better in quality. I don’t know what else to try
#18 by Mikko Koppanen on August 19, 2008 - 2:20 pm
Quote
Felix,
now I got what you’re after. Try this:
$im = new imagick();
$im->setSize(500,500);
$im->readImage(“TEST.svg”);
$im->writeImage(“processed.png”);’
#19 by Felix on August 19, 2008 - 2:41 pm
Quote
Doesn’t work for me
it doesn’t do anything. I tried your exact code, I tried calling the setSize function before and after the readImage call, and still nothing, the image remains to its nominal size of 300×200 no matter what
.
BTW, I think I found a bug in Imagick: if you try to call writeImage() on a file that doesn’t have write permissions, it kills php completely and the webserver sends absolutely nothing (not even headers).
#20 by Felix on August 20, 2008 - 12:52 pm
Quote
Any other ideas?
If you want you can e-mail me, if you feel that this is not the place for this conversation, or should I go to the ImageMagick forums? Thanks
#21 by Felix on August 23, 2008 - 4:48 pm
Quote
I’ve found a way to do it. If anyone else needs this have a look here: http://www.imagemagick.org/discourse-server/viewtopic.php?f=18&t=11909
#22 by Guillaume on September 16, 2008 - 2:08 am
Quote
Thank you so much Mikko for having made ImageMagick available in PHP5 ! That’s awesome.
However after having tried the Fill Pattern example successfully under Ubuntu 8.04 (Hardy) I got errors when porting my code to the production server which runs under Etch.
The ::composite and ::setFillPatternURL methods both fire “no encode delegate for this image format `’” errors and ::annotation fires “Font needs to be set before annotating an image”, and, consequently, drawImage fires “Non-conforming drawing primitive definition `fill’”.
It appears that imagemagick installed versions are 6.2.4 on Etch and 6.3.7 on later versions (Lenny and next).
I have tried a backport of Imagick from Lenny to Etch but it sounds that it won’t be an easy job.
Note, if useful: The server uses PHP 5.2.0-8+etch11 and my station PHP 5.2.4-2ubuntu5.3
I don’t have, unfortunately, any chance to upgrade this server and wonder what I could do now to embed text into a picture…
Any help would be more than welcome.
#23 by Colnector on September 19, 2008 - 5:49 pm
Quote
Hi Mikko,
Your site has wonderful examples. It’s a shame not more of those are in PHP’s manual since Imagick extension is really very useful.
My question is regarding creating a ‘fake’ transparent background with floodfill. I’ve managed to find an ImageMagick example but couldn’t figure out yet how to use Imagick to do the same.
Here:
http://www.imagemagick.org/Usage/channels/
â€
convert cyclops.png -bordercolor white -border 1×1 -matte \
-fill none -fuzz 20% -draw ‘matte 0,0 floodfill’ \
-shave 1×1 cyclops_flood_3.png
â€
Thanks
(sorry for double-posting also at the ‘About’ entry but here seems more active…)
#24 by Guillaume on September 23, 2008 - 1:19 am
Quote
Hi there,



I found ways to bypass my issues
The available fonts can be retrieved by the command `$ convert -list type` on etch (and by the command `$ convert -list font` on more recent versions). And it clearly shows the impressive improvement between 6.2.4 and 6.3.7
I removed the usage of a pattern for the font color and used instead a $draw->setFillColor(new ImagickPixel(‘black’)); :’(
And finished by a $canvas->scaleImage instead of $canvas->adaptiveResizeImage
(shouldn’t I organise now a demonstration in streets to claim for upgrading this server?)
Cheers,
Guillaume
#25 by Dady on October 4, 2008 - 7:58 pm
Quote
Hello,
I have a serious problem to reproduce the command -dissolve with imagick.
For exemple, can not do that to reproduce under imagick :
composite -dissolve 10 -gravity center over.png bg.png -matte out.png
Do you have an idea ?
Sorry for my English (I’m French).
Thank you for your site Mikko.
#26 by Sebastian on November 8, 2008 - 2:52 am
Quote
Could you give us an example with masks ?
Cause I need to realize something similar like this…
You have a background-image, and on that image a Text saying “Hello World”
And then a small car(/something) that is driving from the left to the right revealing the letters like this.
(car = #)
He#
Hello#
Hello Wor#
Hello World #
The car logically has some windows, so you could see some stuff(background+text) through the windows and behind the car but in front the text would be invisible
Thanks and great job what your doing here
!
#27 by Sebastian on November 8, 2008 - 4:50 am
Quote
Hey,
when using
php_imagick_dyn-Q16.dll
every example seems to work except this fill pattern example.
The $draw->setFillPatternURL( ‘#ice’ ); seems to have no effect.
Result is a white image (with black border)
with $draw->setFillColor( “#4096EE” ); it works
Now I switched to php_imagick_st-Q16.dll with which everything works (*me happy*)
I thought I should mention this.
#28 by Dragan on December 1, 2008 - 2:25 pm
Quote
I am happy to find this example, however on my IM installation php5-imagick on debian etch, this error is spit out:
Fatal error: Uncaught exception ‘ImagickDrawException’ in /home/dragan.espenschied/public_html/im/pattern.php:37 Stack trace: #0 /home/dragan.espenschied/public_html/im/pattern.php(19): ImagickDraw->setfillpatternurl(‘#ice’) #1 {main} thrown in /home/dragan.espenschied/public_html/im/pattern.php on line 19
Line 19 is exactly where the fill pattern URL is assigned to the $draw object. Does anybody know what’s wrong here?
Thanks, Dragan
#29 by PlayerOne on December 9, 2008 - 12:15 am
Quote
Very nice work, really !!!
I am amazed.
#30 by issin on December 16, 2008 - 7:56 am
Quote
Nice, thanks for the share.
#31 by Sprille on February 16, 2009 - 3:31 am
Quote
Great work your doing here, i finanly managed to get my imagemagick up and running, thanks.
Also a lot of usefull samples
One thing missing is how to create dynamic text, without the need to know the image size. Is that even possible ?
Got a sample code for the dos convert method, that goes like this:
convert -background none -fill DodgerBlue -stroke black -font Candice -pointsize $pointsize label:”Hello World” -trim +repage ( +clone -alpha extract -blur 0×8 -shade 110×30 -normalize -function polynomial 3.5,-5.05,2.05,0.3 -alpha On ) -compose HardLight -composite aqua_text.png
This produces an image of any size depending on the text passed to it, might as well had been something else, and image would just resize to fit the text.
Any possibilities that you could translate this ?, or point me to somewhere i could read up on it.
Anyway, thanks for the guides, and the dll’s.
#32 by SImon Says on July 24, 2009 - 7:26 pm
Quote
@Sprille: i’m exactly looking for the same thing! what did you find out about it??
#33 by Oto on October 17, 2009 - 7:57 pm
Quote
How can I add pattern to image imagick object, not to text or any ImagickDraw object?
Also if it is possible to do blend like multiply, hard light or something like that?
#34 by Bryan on October 19, 2009 - 3:16 am
Quote
Hi Mikko,
Your example is great, much quicker than using the convert exec commands from inside php. However, I need to know the size of the ImagickDraw object.
In your example, instead of hard coding the text, I have it as a variable that the user can enter in manually.
/* Annotate some text */
$draw->annotation(5, 50, $text);
Imagick() objects have the function getImageHeight and getImageWidth to know the dimensions, but ImagickDraw objects do not. So how can I get the proper size of the $text in the $draw object to use for the newImage call for the Imagick canvas?
-Bryan
#35 by Mikko Koppanen on October 19, 2009 - 10:22 am
Quote
Bryan,
You can use http://uk2.php.net/manual/en/function.imagick-queryfontmetrics.php to get query information about the text.
#36 by Bryan on October 20, 2009 - 5:53 am
Quote
How do you decypher the data? I tried to add this to your example:
/* Create a new imagick object */
$im = new Imagick(‘iceformations5679.JPG’);
/* Create imagickdraw object */
$draw = new ImagickDraw();
/* Start a new pattern called “ice” */
$draw->pushPattern(‘ice’, 0, 0, 50, 50);
/* Composite the image on the pattern */
$draw->composite(Imagick::COMPOSITE_OVER, 0, 0, 50, 50, $im);
/* Close the pattern */
$draw->popPattern();
/* Use the pattern called “ice” as the fill */
$draw->setFillPatternURL(‘#ice’);
/* Set font size to 52 */
$draw->setFontSize(52);
/* Annotate some text */
$draw->annotation(5, 50, $text);
/* get the metrics */
$dimension = $im->queryFontMetrics($draw, $text);
/* Create a new canvas and white image */
$canvas = new Imagick();
$canvas->newImage($dimension['textWidth'], $dimension['textHeight'], “white”);
/* Add black border around the resulting image */
$canvas->borderImage(‘black’, 1, 1);
/* Draw the ImagickDraw on to the canvas */
$canvas->drawImage($draw);
/* Set the format to PNG */
$canvas->setImageFormat(‘png’);
/* Output the image */
header(“Content-Type: image/png”);
echo $canvas;
exit;
But the exclamation point gets cut off because it’s not wide enough and the box is a bit tall as well.
-Bryan
#37 by Faggot54 on October 23, 2009 - 4:59 am
Quote
My concern is rather intentional or not, the tone and replies strike me as a desire to steer as clear away from rape as possible when the issue of rape and the consequences of are are central. ,
Pingback: Imagick blog » Blog Archive » Fill patterns
#38 by Morgon on May 2, 2010 - 6:47 pm
Quote
I do hope Mikko (or anyone else who can help) still reads this particular post.
I’m unable to get this working! PHP 5.3.2 with ImageMagick 6.6.1-5 and imagick 2.3.0 (and I’ve even tried 3.0.0 RC1 with no luck).
Basically, the patterns are not working. Both PHP’s example and this exact example (which is similar to the one on php.net) result in a white image (with the nice black border, of course).
Could it be my version of ImageMagick is too new? I see some ‘deprecated’ warnings when building imagick against it.
Thanks!
#39 by René on June 29, 2011 - 7:01 pm
Quote
Thanks for this resource of ImageMagick. You saved my day
May you can write something about compositeImage with transparent images?
Greetings René
#40 by Logo EPS on April 14, 2012 - 7:40 am
Quote
I have same question: http://valokuva.org/?p=102#comment-5468