views:

719

answers:

2

I am trying to understand how to remove frames from an animated GIF.

Currently I am trying this (as a test):

$count = 1;
foreach ($_im AS $frame) {
    if ($count > 1) { $frame->removeImage(); }
    $count++;        
}

However this seems to toast everything in the object.

Suggestions from workmates have been to just create another IM object, and extract a famee into it, etc. That seems extremely messy however.

+1  A: 

I have only used the command line utilities for IM.

convert srcImage.gif[0] dstImage.gif

Should do the trick unless I forgot an option.

[0] referes to the first frame of the animated gif.

Flugan
So this more or less pulls the first frame out and puts it in another file? Hmm ok. That is what my colleague suggested, but it sounded messy. I guess I'll go that direction. Thanks.
Spot
+2  A: 

Hi,

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 :

  • create a new image
  • iterate over the frames of the orignal one
  • if the current frame is one I want to keep, copy it to the new image


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 :-(

Pascal MARTIN
Thanks a lot. If this is the only way to do it, then that's what I'll do. :) Really appreciate the concise response.
Spot
You're welcome :-) Have fun !
Pascal MARTIN