With some animated GIFs, for subsequent frames, the only data that is stored, is the difference compared to an earlier frame. Now, I've only just touched the surface of the internal workings of the data structure of (animated) GIFs, but I believe this is done with what is either called compression, frame difference, or disposal (not entirely sure, actually).
With Gmagick, or Imagick, for PHP, how do I extract each frame (write them out) such that not just this minimal data is extracted, but the complete representation of that frame as it is visually intended?
I've tried the following with Gmagick so far, to no avail, unfortunately:
// as per this comment:
// http://php.net/manual/en/imagick.setimagedispose.php#95701
// I've tried values in the range 0-4 here:
$img->setImageDispose( 0 ); // $img is animated GIF instance of Gmagick
$frameIndex = 0;
do
{
$img->setImageIndex( $frameIndex );
$frame = $img->getImage();
$frameName = ++$frameIndex . '.gif';
$frame->writeImage( $frameName, false ); // or:
// $frame->write( $frameName );
}
while( $img->hasNextImage() );
I've tried a few other things as well, such as Gmagick::setImageScene()
, etc. But nothing works. I am only able to save the frame difference data, not the data such as visually intended.
I found out on my own how to do it with Imagick:
$frameIndex = 0;
$img = $img->coalesceImages();
foreach( $img as $frame )
{
$frameName = ++$frameIndex . '.gif';
$frame->writeImage( $frameName );
}
In other words, Imagick::coalesceImages()
did the trick.