Trying to figure out a way in my bash script to check if a file is an animated PNG (apng) file. In my case I want to ignore it if it is . Any ideas ?
UPDATE: The answer below using pngcheck allowed me to check if the image was an animation. In addition I check the size of the file, if it's "large" I ignore it as well. Lastly, as of Nov 2017, "identify" does NOT work which was my initial issue mainly. Thanks Mark for your help.
An animated PNG is characterised by the presence of an
acTL
(Animation Control Chunk), andfcTL
(Frame Control Chunks) - see Wikipedia article.So, I think a suitable test would be to run
pngcheck
with the verbose option, and look for at least theacTL
chunk:Sample Output
So, that would suggest this test in a script:
If you don't have, or don't want to ship
pngcheck
with your project, I made a little Perl script that just de-chunks a PNG file and tells you the chunks and offsets and it should run anywhere since it is Perl. You are welcome to use it.Sample Run
I don't see a "good" way to do this, so I'm going to cheat. First, my attempts:
Two test images: An elephant and a ball. They're actually quite distracting, so I'll let you open them separately rather than including them here (I just burned a whole minute staring blankly at them).
Let's rename them
elephant.apng
andball.apng
for simplicity.So libmagic (File 5.32, either without options or by requesting a MIME type) and identify (ImageMagick 6.9.7-4) and strings (GNU Binutils 2.29.1) with grep (GNU grep 3.1) all fail to find anything aside from a watermark left by APNG Assembler, which can't be guaranteed.
Now let's cheat. I'm going to assume that lots of entropy means it's an animated PNG (rather than something else, like a steganographic message) and merely run this through ImageMagic
convert
to turn it into a standard PNG:Okay, we can work with that:
This sets
size1
to the size of the image in bytes (usingwc -c
to get the character count), then setssize2
to the size of the image after "converting" it to a PNG (-
tells convert to push the final image to standard output andwc
reads that in). Ifsize1
is at least twice as big assize2
then we assume it's an animated PNG.That's in a loop, so you can call it on any number of image files (even non-PNGs, though that doesn't make much sense and you'll always be told it's a PNG of some sort). Note, you can't pipe into it because it'd absorb standard input on the first
wc
call and have nothing left over for the conversion.If you have MediaInfo installed (e.g.
apt install mediainfo
), you can (temporarily!) detect something amiss with this command:I'm not exactly sure what that means, but it doesn't show up on my converted PNGs, so it might be safe … at least until MediaInfoLib actually support APNG file formats (this is why I said "temporarily"). This works in v0.7.99 at least.
Invoke as
grep -q
to make that silent for yourif
tests.First extract the extension of your file using
expr
.Check http://tldp.org/LDP/abs/html/string-manipulation.html:
Then compare extracted extension with ".png"