ImageMagick: GIF to sprite sheet - every second frame is empty

-1

I'm trying to convert GIF to sprite sheet sequence (to .png) using ImageMagick. Right now I'm using these two commands:

convert -layers dispose ezgif.gif tmp.gif

montage tmp.gif -tile x1 -geometry '1x1+0+0<' -alpha On -background 'rgba(0, 0, 0, 0.0)' -quality 100 seq.png

This works very well on most of GIFs but on this one, it doesn't.

https://i.projectbea.st/WF2ygx.gif

It looks all well here. But when I convert it, you can see that every second frame is empty.

https://i.projectbea.st/pJAlq1.png

Why and how to fix it?

GTX

Posted 2016-09-30T21:22:04.383

Reputation: 101

Neither of your image URLs work due to an invalid SSL certificate. I suggest that you upload them to Imgur or other image hosting site. Please see [ask] and take our [tour]. – Burgi – 2016-10-09T16:11:16.373

I lost all the data. It seems like it is impossible to fix this anyways so... – GTX – 2016-10-09T17:29:28.770

Answers

1

The reason for that is, obviously, because every second frame in the original gif image is empty. Each empty layer is set to merge with previous one instead of replacing it, much like ImageMagick allows with dispose command. You can look closer at it with Gimp.

To eliminate the empty frames you would have to do it manually or with a script, eg. split the image to a series of files, delete every second frame and merge them back into the original gif. Example is here.

Edit: Since the gif images are user input, I'm afraid there isn't a 100% sure way to automate this. You can detect if the frame is empty (contains single color), but you'll be cutting down gif images that contain single color frames intentionally. Futhermore there could be single color frames that add only partial overlay.

Here is a crude bash script removing single color frames using information from the imagemagick identify command.

#!/bin/bash

convert animation.gif +adjoin tmp_%04d.png

j=0
for i in $(ls tmp_*.png); do 
  if [ $(identify -verbose $i | grep Colors: | awk '{ print $2; }') != "1" ]; then
    cp $i select_$(printf %04d $j).png;
    (( j++ ))
  fi
done

montage $(ls select_*) -tile x1 -geometry '1x1+0+0<' -alpha On -background 'rgba(0, 0, 0, 0.0)' -quality 100 result.png

Marek Rost

Posted 2016-09-30T21:22:04.383

Reputation: 1 826

If I delete every second frame then it will skip frames for other GIFs. (The GIFs are uploaded by users) – GTX – 2016-09-30T22:35:14.217