Today’s example was requested by a user called Devo. This example illustrates making an animated GIF image by creating the frames from scratch. It’s been so long since I’ve really drawn anything so I decided to use text as the base for this animation.
You could of course use existing images to simulate motion or even strip frames from videos to create GIF animations. The example is pretty straightforward but please post any questions you might have.
- <?php
- /* This object will hold the animation */
- $animation = new Imagick();
- /* Set the format to gif. All created images will be gifs*/
- $animation->setFormat( "gif" );
- /* Create a pixel to handle colors */
- $color = new ImagickPixel( "white" );
- /* The first frame */
- $color->setColor( "white" );
- /* This is the string we print on the image
- Character by character */
- $string = "HELLO WORLD!";
- /* Create a new ImagickDraw object and set the font
- Text color defaults to black */
- $draw = new ImagickDraw();
- /* You can get configured fonts with $im->queryFonts
- or use /path/to/file.ttf */
- $draw->setFont( "Helvetica" );
- /* Loop trough the string.. */
- for ( $i = 0; $i <= strlen( $string ); $i++ )
- {
- /* Take some characters for this frame */
- $part = substr( $string, 0, $i );
- /* Create a new frame */
- $animation->newImage( 100, 50, $color );
- /* Annotate the characters on the image */
- $animation->annotateImage( $draw, 10, 10, 0, $part );
- /* Set a little higher delay for the frame*/
- $animation->setImageDelay( 30 );
- }
- /* The last frame contains the same text with bold */
- $draw->setFont( "Helvetica-Bold" );
- /* One more frame */
- $animation->newImage( 100, 50, $color );
- /* Annotate the bold text on the image */
- $animation->annotateImage( $draw, 10, 10, 0, $string );
- /* The bold can be visible a little longer time */
- $animation->setImageDelay( 60 );
- /* Display the output as an animation.
- Use getImagesBlob to get all images combined */
- header( "Content-Type: image/gif" );
- echo $animation->getImagesBlob();
- ?>
This is how the resulting image looks like:

#1 by Masood Ahmad Ansari on October 10, 2007 - 12:39 pm
Quote
Hi Mikko Koppanen
i found this blog very interesting . Thanx a lot
i was trying to create animated gif from an array of images but its not working as expected. only two images are shown and no looping takes place… here is the code
header( “Content-Type: image/gif” );
$animation = new Imagick();
$animation->setFormat( “gif” );
$images=array(“image0.gif”,”image1.gif”,”image2.gif”,”image3.gif”,”image4.gif”);
for ( $i = 0; $i setImageDelay( 90 );
$animation->addImage($img);
}
echo $animation->getImagesBlob();
please help
#2 by Masood Ahmad Ansari on October 10, 2007 - 12:42 pm
Quote
sorry the pasted code does not show up correct. pasting it again. the code is sytactically correct .
header( “Content-Type: image/gif” );
$animation = new Imagick();
$animation->setFormat( “gif” );
$images=array(“image0.gif”,”image1.gif”,”image2.gif”,”image3.gif”,”image4.gif”);
for ( $i = 0; $i <=4; ++$i )
{
$img=new Imagick($images[$i]);
$img->setImageDelay( 90 );
$animation->addImage($img);
}
echo $animation->getImagesBlob();
#3 by Mikko Koppanen on October 10, 2007 - 2:15 pm
Quote
You could try something like this:
$animation = new Imagick();
$images = new Imagick( array(â€image0.gifâ€,â€image1.gifâ€,â€image2.gifâ€,â€image3.gifâ€,â€image4.gifâ€) );
foreach ( $images as $key => $image )
{
$animation->addImage( $image );
$animation->setImageFormat( “gif” );
$animation->setImageDelay( 90 );
$animation->setIteratorIndex( $key );
}
header( “Content-Type: image/gif†);
echo $animation->getImagesBlob();
Trackback: PHPDeveloper.org
Pingback: developercast.com » Mikko Koppanen: Requested examples: Animating GIF Images
#4 by Mark on October 11, 2007 - 12:24 am
Quote
Hey Mikko,
seems like you’re gettin’ famous heh
#5 by Devo on October 11, 2007 - 10:08 am
Quote
Thanks Mikko. That was just what I was looking for to get started.
After seeing how it worked, here is how I ended up doing my image slideshow (basic):
// create a new imagick object filled with four images to use as frames in the animation
$im = new Imagick( array( “img1.jpg”, “img2.jpg”, “img3.jpg”, “img4.jpg” ) );
foreach ( $im as $key => $image ) {
$image->thumbnailImage( 200, null ); // thumbnail the image (optional)
$image->roundCorners( 5, 5 ); // round the corners a bit (optional)
$image->setImageFormat( “gif” ); // set format to gif
$image->setImageDelay( 150 ); // add a delay to the frame
}
header( “Content-Type: image/gif” ); // output gif header
echo $im->getImagesBlob(); // output images
#6 by Jon on November 3, 2007 - 8:16 am
Quote
Can you give an example of how to increase the size of the “Hello World” font?
#7 by Fran GarcÃa on November 12, 2007 - 8:45 pm
Quote
Has anybody any idea how it could be possible to resize an animated gif using the Imagick library instead of the command “convert”?
#8 by Mikko Koppanen on November 12, 2007 - 8:56 pm
Quote
Fran GarcÃa,
use thumbnailImage and after that setImagePage.
#9 by Fran GarcÃa on November 12, 2007 - 9:36 pm
Quote
Thanks Mikko for your quick answer. I’ll try it!
#10 by Fran GarcÃa on November 13, 2007 - 12:14 am
Quote
Hi Mikko,
could you give an example how to use the function setImagePage();
I have something like this:
$image->thumbnailImage(60,0);
$image->setImagePage(60,0,0,0);
But it doesn’t work fine and the animation disappears.
Thanks in advance Mikko!
#11 by Mikko Koppanen on November 13, 2007 - 12:25 am
Quote
Fran Garcia,
you have to loop trough all frames. I can’t really help you without seeing the full code.
#12 by Fran GarcÃa on November 13, 2007 - 8:29 pm
Quote
I think you have seen all my code, but now I know that I have to loop through all the frames. The problem is that the function setImagePage use four parameters which I don’t really know its meaning.
#13 by Mikko Koppanen on November 14, 2007 - 12:00 am
Quote
Fran,
bool Imagick::setImagePage ( int $width, int $height, int $x, int $y )
width: the width of the visible area
height: the height of the visible area
x: the top left corner x-coordinate
y: the top left corner y-coordinate
Think about it as an rectangle which is overlayed on the image. You give x,y position of the top left corner, top right is x + width and so on.
#14 by George Maicovschi on November 30, 2007 - 3:25 pm
Quote
Hi Mikko,
Firstly, this is a kick-ass script all in all.
But i have a question for you. Is there any way i can fill te text with a pattern from an external image?
Thanks in advance and all the best. Extraordinary work anyhow!
#15 by Mikko Koppanen on November 30, 2007 - 5:04 pm
Quote
George,
I’m not sure if tiling text with different image is supported. You can propably use some composition hackery on that.
#16 by George Maicovschi on November 30, 2007 - 5:09 pm
Quote
Mikko,
Thanks for your response. Too bad to hear that such a thing is not yet implemented. Could you give me a heads-up about how i could trick imagick and emulate this kind of behaviour?
Thanks again.
#17 by Mikko Koppanen on November 30, 2007 - 5:17 pm
Quote
George,
See progress in this thread http://www.imagemagick.org/discourse-server/viewtopic.php?f=6&t=10229&sid=a17c10d36379bdb65012b4da5afc385d
#18 by George Maicovschi on November 30, 2007 - 5:30 pm
Quote
Thanks, I will keep an eye on it.
#19 by George Maicovschi on November 30, 2007 - 5:59 pm
Quote
Me again. I know i might be getting quite stressing for you…
But one more question. Is there any way that i can convert a text to a clipping path so that i can make a mask out of it and thus fill the layer behind it with the pattern using textureImage?
The only problem is that making the text transparent is not an option because the background of the texzt must be transparent…
Any new ideas?
#20 by Barry on March 2, 2008 - 5:59 pm
Quote
Hello mate,
Any ideas on how to create something like this ?
http://www.imagemagick.org/Usage/anim_basics/rose_sparkle.gif
#21 by Cristian on May 13, 2008 - 1:36 am
Quote
Hello,
A very useful tutorial, I must thank you for it.
I have a small question … I try to set the font family, and $draw->setFont( “./Lucida-Sans-Unicode.ttf” ); doesn’t seem to do it.
I must mention that the Lucida-Sans-Unicode.ttf font is in the same directory as the script, but it is not installed on the server where I’m hosting the website.
Thank you for your time,
Cristian
#22 by Nix on May 28, 2008 - 4:49 pm
Quote
Hi Mikko Koppanen
great tut! Was wondering if i can save the image to file with the animation by adding the $animation->writeImage(“THIS.gif”); – but will i need something like – $animation->getImagesBlob(); to bring frames together?
Also – if that is possible if i can also add other things onto the canvas such as an image that will be static throughout?
Thanks in advance
Nix
#23 by Mikko Koppanen on May 28, 2008 - 4:56 pm
Quote
Nix,
there is a method called writeImages. That is probably what you’re after.
#24 by Nix on May 28, 2008 - 5:10 pm
Quote
thanks for the quick reply but that doesnt really answer my question – if i use $animation->writeImage(â€THIS.gifâ€); which is from your example about – it just creates an image that is static with the words HELLO WORLD! – is it possible to save that image as an animation?
#25 by Mikko Koppanen on May 28, 2008 - 5:16 pm
Quote
Nix,
I said writeImages not writeImage.
#26 by Nix on May 28, 2008 - 5:22 pm
Quote
$animation->writeImages(‘this11.gif’, true);
Got it thanks
thats great
#27 by Nix on May 28, 2008 - 5:43 pm
Quote
how would i add my animation to my canvas that contains other elements in it such as other images and text.
So i have a canvas with elements on it -
an animation text hello world! $animation->newImage( 100, 50, $color ); from your example
I have added my other elements to canvas –
$canvas->compositeImage($image_object_1, imagick::COMPOSITE_OVER, $image_object_1_x, $image_object_1_y);
$canvas->drawImage($draw_text_2);
$canvas->drawImage($draw_text_1);
How can i now add my animation to this?
Thanks for you time
Nix
#28 by Mikko Koppanen on May 28, 2008 - 5:48 pm
Quote
Nix,
that makes absolutely no sense to me.
Trackback: prilozec medication
#29 by Jan on September 18, 2008 - 12:14 pm
Quote
Hi MIko
how can i combine text with different color
like :
// weight
$draw->setGravity( Imagick:: GRAVITY_NORTH );
// first text color
$draw->setFillColor(new ImagickPixel(“green”));
$im->annotateImage( $draw, 0, 0, 0, “first text” );
$im->drawImage($draw);
// second text
$draw->setFillColor(new ImagickPixel(“green”));
$im->annotateImage( $draw, 0, 0, 0, “this is the second text” );
$im->drawImage($draw);
now the second text overlap the first text but the output should be
first text this is second text
- so in just one line paragraph a combination of two or more text with different color
TIA
#30 by Kapil on September 24, 2008 - 11:23 am
Quote
The animation as per above code you specified plays only once, how to loop infinitely without doing it from cmd line of imagick, instead using PHP.
Please reply ASAP.
#31 by Victoriya on February 10, 2009 - 7:01 pm
Quote
Nice news, grazie!
#32 by John on March 5, 2009 - 8:09 pm
Quote
How do I look through the frames in an animated gif?
For example, I’ve tried something like this:
$image = new Imagick(“someanimated.gif”);
$count = 1;
while ($count getNumberImages())
{
$image->thumbnailImage(60,0);
$image->setImagePage(60,0,0,0);
$image->nextImage();
$count++;
}
header(“Content-Type: image/gif”);
echo “”.$image.”";
But it doesn’t output an animated gif, just a single frame.
#33 by John on March 5, 2009 - 8:12 pm
Quote
Also, there is a less than or equal to sign in that while statement but for some reason it’s not showing up when I post. Anywho, any suggestions about how to loop through each frame in an animated gif would be very much appreciated.
#34 by Richard on April 7, 2009 - 3:56 am
Quote
Is there a way to implement the example shown in post #3 of this thread except using php file handles rather than strings containing file names? This would simplify using the tmpfile() function to manage cleanup of the component files.
#35 by TommyGFX on April 20, 2009 - 11:44 pm
Quote
Sorry for code !!!
// create a new imagick object filled with four images to use as frames in the animation
$im = new Imagick( array( “img1.jpgâ€, “img2.jpgâ€, “img3.jpgâ€, “img4.jpg†) );
foreach ( $im as $key => $image ) {
$image->thumbnailImage( 200, null ); // thumbnail the image (optional)
$image->roundCorners( 5, 5 ); // round the corners a bit (optional)
$image->setImageFormat( “gif†); // set format to gif
$image->setImageDelay( 150 ); // add a delay to the frame
}
header( “Content-Type: image/gif†); // output gif header
echo $im->getImagesBlob(); // output images
How can I store a gif image but it is animated?
#36 by Allen on April 29, 2009 - 2:31 pm
Quote
I have a question. what if I need to composite an image to the gif image? is it possible?
#37 by Mikko Koppanen on May 2, 2009 - 2:06 am
Quote
TommyGFX,
writeImagesBlob()
#38 by TommyGFX on May 5, 2009 - 9:02 pm
Quote
Call to undefined method Imagick::writeImagesBlob()
#39 by unregistr3d on May 27, 2009 - 5:45 pm
Quote
Hi,
i can’t get it to work, i even tried that one you posted bevore. But it will not loop. 3 Frames are shown, and then it stops. The Delay time doesn’t change anything, 900 is the same speed as 10.
$image )
{
$animation->addImage( $image );
$animation->setImageFormat( ‘gif’ );
$animation->setImageDelay( 900 );
$animation->setIteratorIndex( $key );
}
header( ‘Content-Type: image/gif’ );
echo $animation->getImagesBlob();
?>
#40 by Mikko Koppanen on June 10, 2009 - 11:41 am
Quote
@Sanjay
http://www.imagemagick.org/Usage/thumbnails/#rounded_border
#41 by Anatoly on January 2, 2010 - 6:36 pm
Quote
Excuse for bad English. But at me a question how to use function coalesceImages ()? Many days I try to understand with this function, but receives nothing
Pingback: links for 2010-01-21 « ueXpected
#42 by AzHofi on February 3, 2010 - 9:15 pm
Quote
Thanky, You helped me a lot!
#43 by Rahul on June 29, 2011 - 10:38 pm
Quote
Can we change the foreground and background color of animated gif images (off-course without losing their animation)?
Can you please let me know How can we do this using PHP?
Ref: a website ajaxload[dot]info is doing the same thing.
Please do post a new thread on this, thanks.