I need to resize an animated GIF file without destroying the animation.
How can I do it using PHP?
I need to resize an animated GIF file without destroying the animation.
How can I do it using PHP?
I've been going through the Imagick
documentation for a while, and tried a couple of things... But I didn't manage to do what you want either -- so, we are at least two who can't find out a clean way ^^
Anyway, the only way I managed to remove a frame for an animated GIF image was by creating a new one, containing only the frames I didn't want to remove :-(
Considering I loaded an image this way :
// Load the existing image
$image = new Imagick(dirname(__FILE__) . '/animated-gif-source.gif');
(This is an animated gif, with 3 frames ; I want to "remove" the second one).
As I said, only way I found to "remove a frame" is this one :
$new_image = new Imagick();
$i = 1;
foreach ($image as $frame) {
if ($i===1 || $i===3) {
// 3 frames ; we keep the first and third one
// ie, remove the second one
$new_image->addImage($frame->getImage());
}
$i++;
}
So :
And, in the end, to output the image to the browser :
// To directly output to the browser
header('Content-Type: image/gif');
echo $new_image->getImagesBlob();
Or, to write it to a file :
// To write the new image to a file
// Must use writeImages, and not writeImage (multi-frames ! )
$new_image->writeImages(dirname(__FILE__) . '/animated-gif-output.gif', true);
Each one of these outputs only contain the first and third frames ; so, it's working...
But, as you said, it doesn't feel good :-(
It will probably work just fine for most images, I think ; you might encouter troubles with big images, but animated GIFs are generally not that big... are they ?
Other way might be using convert from the command line... But... not that great, and I didn't find a way to just remove a frame with those either :-(
You need to loop through the frames in the animated GIF and resize each one.
May also want to take a look at GifLib.
The best examples are located in the unit-tests shipped with the code. wand/tests/sequence_test.py
for example.
For creating an animated gif with wand, remember to load the image into the sequence, and then set the additional delay/optimize handling after all frames are loaded.
from wand.image import Image
with Image() as wand:
# Add new frames into sequance
with Image(filename='1.png') as one:
wand.sequence.append(one)
with Image(filename='2.png') as two:
wand.sequence.append(two)
with Image(filename='3.png') as three:
wand.sequence.append(three)
# Create progressive delay for each frame
for cursor in range(3):
with wand.sequence[cursor] as frame:
frame.delay = 10 * (cursor + 1)
# Set layer type
wand.type = 'optimize'
wand.save(filename='animated.gif')
Yes, you can set the gif image but this will not animate your gif image. You need to explicitly extract the gif image into all frame and then using animate you image as gif here is the example of
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false" >
<item
android:drawable="@drawable/framelayout1"
android:duration="1000"/>
<item
android:drawable="@drawable/framelayout2"
android:duration="1000"/>
<item
android:drawable="@drawable/framelayout3"
android:duration="1000"/>
<item
android:drawable="@drawable/framelayout4"
android:duration="1000"/>
....
</animation-list>
if you have imagemagick access, you can do this:
this is most likely possible with the imagemagick plugin if you don't have system() access
NOTE: this may create a larger filesize though a smaller dimensions image due to coalescing essentially deoptimizing the image.
UPDATE: If you don't have ImageMagick access, you should be able to use a combination of the following steps to resize an animated gif (assuming you have GD access):
This is definitely much more intensive than the ImageMagick route, but it should be technically possible.
If you get it working, please share with the world!