Bash脚本检查图像是否为动画png(apng) [英] Bash script check if image is animated png (apng)

查看:216
本文介绍了Bash脚本检查图像是否为动画png(apng)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图在我的bash脚本中找出一种方法来检查文件是否为动画PNG(apng)文件。就我而言,我想忽略它。有什么想法吗?

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 ?

更新:
下面使用pngcheck的答案使我可以检查图像是否是动画。此外,我还会检查文件的大小,如果文件过大,我也会忽略它。最后,截至2017年11月,识别不起作用,这主要是我最初的问题。谢谢Mark的帮助。

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.

推荐答案

动画PNG的特征是存在 acTL (动画控制块)和 fcTL (帧控制块)-请参见维基百科文章

An animated PNG is characterised by the presence of an acTL (Animation Control Chunk), and fcTL (Frame Control Chunks) - see Wikipedia article.

因此,我认为合适的测试方法是运行 pngcheck 和verbose选项,并至少查找 acTL 块:

So, I think a suitable test would be to run pngcheck with the verbose option, and look for at least the acTL chunk:

pngcheck -v animated.png | grep -E "acTL|fcTL"

示例输出

  chunk acTL at offset 0x00025, length 8
  chunk fcTL at offset 0x00039, length 26
  chunk fcTL at offset 0x02f27, length 26
  chunk fcTL at offset 0x05901, length 26
  chunk fcTL at offset 0x083a2, length 26
  chunk fcTL at offset 0x0aea8, length 26
  chunk fcTL at offset 0x0d98c, length 26
  chunk fcTL at offset 0x10406, length 26
  chunk fcTL at offset 0x12e19, length 26
  chunk fcTL at offset 0x15985, length 26
  chunk fcTL at offset 0x185e2, length 26
  chunk fcTL at offset 0x1b2b0, length 26
  chunk fcTL at offset 0x1dfe1, length 26
  chunk fcTL at offset 0x20d24, length 26
  chunk fcTL at offset 0x23a03, length 26
  chunk fcTL at offset 0x26663, length 26
  chunk fcTL at offset 0x29218, length 26
  chunk fcTL at offset 0x2bcdf, length 26
  chunk fcTL at offset 0x2e7e0, length 26
  chunk fcTL at offset 0x312b0, length 26
  chunk fcTL at offset 0x33c51, length 26
  chunk fcTL at offset 0x36598, length 26
  chunk fcTL at offset 0x38f49, length 26
  chunk fcTL at offset 0x3b9bd, length 26
  chunk fcTL at offset 0x3e45e, length 26
  chunk fcTL at offset 0x40ed9, length 26
  chunk fcTL at offset 0x4393c, length 26
  chunk fcTL at offset 0x46521, length 26
  chunk fcTL at offset 0x4919b, length 26
  chunk fcTL at offset 0x4bde2, length 26
  chunk fcTL at offset 0x4eabd, length 26
  chunk fcTL at offset 0x51827, length 26
  chunk fcTL at offset 0x5453a, length 26
  chunk fcTL at offset 0x571c7, length 26
  chunk fcTL at offset 0x59d94, length 26

因此,这将建议在脚本中进行此测试:

So, that would suggest this test in a script:

# Test an animated image, `grep` exit status is zero meaning `acTL` was found
pngcheck -v animated.png | grep -q "acTL"
echo $?
0

# Test a still image, `grep` exit status is 1 meaning `acTL` was not found
pngcheck -v still.png | grep -q "acTL"
echo $?
1






如果没有有或不想随项目一起运送 pngcheck ,我做了一个Perl脚本,只是解压缩了一个PNG文件,并告诉您块和偏移量及其应该是任何地方都可以运行,因为它是Perl。欢迎您使用它。


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.

样品运行

./pngchunks ball.png

13 IHDR
8 acTL                   <--- This one means it is animated
26 fcTL
4634 IDAT
26 fcTL
4344 fdAT
26 fcTL
4042 fdAT
26 fcTL
3828 fdAT
26 fcTL
3521 fdAT
26 fcTL
3168 fdAT
26 fcTL
2777 fdAT
26 fcTL
2588 fdAT
26 fcTL
2720 fdAT
26 fcTL
2792 fdAT
26 fcTL
2665 fdAT
26 fcTL
2581 fdAT
26 fcTL
2652 fdAT
26 fcTL
2774 fdAT
26 fcTL
2844 fdAT
26 fcTL
2886 fdAT
26 fcTL
2966 fdAT
26 fcTL
3197 fdAT
26 fcTL
3518 fdAT
26 fcTL
3995 fdAT
0 IEND







#!/usr/bin/perl -w
################################################################################
# pngchunks
# Mark Setchell
#
# Simple Perl tool to read the chunks in a PNG image file
# See https://en.wikipedia.org/wiki/Portable_Network_Graphics
#
# Usage: pngchunks image.png
################################################################################
use strict;
use Fcntl qw( SEEK_CUR );

my $f=shift or die "Usage: pngchunks image.png\n";

my ($handle,$offset,$buffer,$type,$length);

# Open file
open($handle,'<',$f) || die("Error opening file\n");

# Check 8 byte PNG signature
read($handle,$buffer,8);
if(substr($buffer,0,8) ne "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"){
   die("ERROR: Invalid PNG signature\n");
}

# Loop till IEND chunk
for(;;){

   # Read 4 bytes of length, Network (big-endian)
   read($handle,$buffer,4);
   $length=unpack("N",$buffer);

   # Read 4 bytes of chunk type
   read($handle,$buffer,4);
   $type=substr($buffer,0,4);

   printf("%d %s\n",$length,$type);

   # Break out of loop if IEND chunk
   last if $type eq "IEND";

   # Seek past this chunk and its 4 byte CRC
   $offset=4+$length;
   seek($handle,$offset,SEEK_CUR);
}

这篇关于Bash脚本检查图像是否为动画png(apng)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆