python 如何以编程方式检查 GIF 图像是否为动画?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1412529/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I programmatically check whether a GIF image is animated?
提问by Joel Verhagen
Here is a link to another questionI asked concerning the same project I am working on. I think that bit of background will be helpful.
这是我就我正在从事的同一个项目提出的另一个问题的链接。我认为那一点背景会有所帮助。
For those that are too lazy to open a new tab to that question, I'll summarize what I'm trying to do here: I've downloaded about 250,000 images from 4scrape and I want to go through the GIFs and find which ones are animated or not. I need to do this programmatically, because I really don't feel my soul (or my relationship with my girlfriend) could use looking at a couple thousand GIFs from 4chan to see if they are animated or not. If you know the nature of 4chan, then you know the nature of the images (i.e. "tits or GTFO").
对于那些懒得打开一个新标签来解决这个问题的人,我将在这里总结我想要做的事情:我从 4scrape 下载了大约 250,000 张图片,我想浏览 GIF 并找出哪些是动画与否。我需要以编程方式执行此操作,因为我真的不觉得我的灵魂(或我与女朋友的关系)可以通过查看 4chan 的数千个 GIF 来查看它们是否具有动画效果。如果你知道 4chan 的本质,那么你就知道图像的本质(即“tits or GTFO”)。
I know PHP and Python, but would be willing to explore other solutions. A stand-alone piece of software that works on Windows would also work.
我知道 PHP 和 Python,但愿意探索其他解决方案。在 Windows 上运行的独立软件也可以运行。
Thanks a lot!
非常感谢!
回答by bobince
回答by Denilson Sá Maia
If you're on Linux (or any system with ImageMagick) you can use a one-liner shell script and identify
program:
如果您使用的是 Linux(或任何带有ImageMagick 的系统),您可以使用单行 shell 脚本和identify
程序:
identify *.gif | fgrep '.gif[1] '
I know you said you prefer PHP and Python, but you also said you are willing to explore other solutions. :)
我知道你说你更喜欢 PHP 和 Python,但你也说你愿意探索其他解决方案。:)
回答by Eric M
I've never seen a program that will tell you this. But GIF is a block structured format and you can check if the block indicating animated GIF is present in your files.
我从来没有见过一个程序会告诉你这个。但是 GIF 是一种块结构格式,您可以检查文件中是否存在表示动画 GIF 的块。
From wikipedia article noted below: at offset 0x30D an Application Extension (ie: 3 byte magic number 21 FF 0B) block in the GIF file, followed by magic number 4E 45 54 53 43 41 50 45 32 9at offset 0x310 indicates that the rest of the file contains multiple images, and they should be animated.
来自下面提到的维基百科文章:在 GIF 文件中的偏移量 0x30D 处有一个应用程序扩展(即:3 字节幻数 21 FF 0B)块,然后是幻数 4E 45 54 53 43 41 50 45 32 9at offset 0x310 表示其余部分该文件包含多个图像,它们应该是动画的。
Really the Wikipedia article explains it better and the format docs noted below expand on the Wiki article.
真的,维基百科文章解释得更好,下面提到的格式文档扩展了维基文章。
So you can parse the GIFs using a program written in Python (I parsed GIFs using C many years ago, it was mainly an exercise in moving the file pointer around and reading bytes). Determine if the AE is present with the correct 3 byte ID, and followed by the 9 byte magic number.
因此,您可以使用 Python 编写的程序解析 GIF(我多年前使用 C 解析 GIF,它主要是移动文件指针和读取字节的练习)。确定 AE 是否存在正确的 3 字节 ID,后跟 9 字节幻数。
See http://en.wikipedia.org/wiki/Graphics_Interchange_Format#Animated_.gif
见http://en.wikipedia.org/wiki/Graphics_Interchange_Format#Animated_.gif
Also see http://www.martinreddy.net/gfx/2d/GIF87a.txt
另见http://www.martinreddy.net/gfx/2d/GIF87a.txt
Also see http://www.martinreddy.net/gfx/2d/GIF89a.txt
另见http://www.martinreddy.net/gfx/2d/GIF89a.txt
Sorry, best I can do for you.
对不起,我能为你做的最好。
回答by qwr
Pillow 2.9.0 added is_animated
:
This adds the property
is_animated
, to check if an image has multiple layers or frames.
这将添加属性
is_animated
, 以检查图像是否具有多个图层或框架。
Example usage:
用法示例:
from PIL import Image
print(Image.open("test.gif").is_animated)
回答by Ben S
A few solutions are given on the PHP docspage for the imagecreatefromgif
function.
该函数的PHP 文档页面上提供了一些解决方案imagecreatefromgif
。
From the solutions I've read, this one seems the best due to its tighter memory requirements.
从我读过的解决方案来看,由于其更严格的内存要求,这似乎是最好的。
<?php
function is_ani($filename) {
if(!($fh = @fopen($filename, 'rb')))
return false;
$count = 0;
//an animated gif contains multiple "frames", with each frame having a
//header made up of:
// * a static 4-byte sequence (\x00\x21\xF9\x04)
// * 4 variable bytes
// * a static 2-byte sequence (\x00\x2C)
// We read through the file til we reach the end of the file, or we've found
// at least 2 frame headers
while(!feof($fh) && $count < 2) {
$chunk = fread($fh, 1024 * 100); //read 100kb at a time
$count += preg_match_all('#\x00\x21\xF9\x04.{4}\x00\x2C#s', $chunk, $matches);
}
fclose($fh);
return $count > 1;
}
?>
回答by Ben S
I'm no GIF file format expert, but this is an interesting problem to me so I looked into it a bit. This would work only if it's always true that animated gifs have the value NETSCAPE2.0 at position 0x310 (edit)AND static gifs do not,(/edit) which was the case in my test files. This is C#, if you want I could compile it to a console app that takes a directory as an argument and you could run some test on your very large gif collection to see if it produces reliable results.
我不是 GIF 文件格式专家,但这对我来说是一个有趣的问题,所以我研究了一下。只有当动画 gif 在位置 0x310 处具有 NETSCAPE2.0 值(编辑)并且静态 gif 没有,(/编辑)这在我的测试文件中就是这种情况时,这才有效。这是 C#,如果您愿意,我可以将其编译为以目录作为参数的控制台应用程序,您可以对非常大的 gif 集合运行一些测试,以查看它是否产生可靠的结果。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string ani = @"C:\path\to\ani.gif";
string sta = @"C:\path\to\static.gif";
Console.WriteLine(isAnimated(ani));
Console.WriteLine(isAnimated(sta));
}
static bool isAnimated(string path)
{
byte[] bytes = File.ReadAllBytes(path);
byte[] netscape = bytes.Skip(0x310).Take(11).ToArray();
StringBuilder sb = new StringBuilder();
foreach (var item in netscape)
{
sb.Append((char)item);
}
return sb.ToString() == "NETSCAPE2.0";
}
}
}
回答by Lothar
Read the GIF89A specification and extract the information. http://www.w3.org/Graphics/GIF/spec-gif89a.txt
阅读 GIF89A 规范并提取信息。 http://www.w3.org/Graphics/GIF/spec-gif89a.txt
Or easy and lazy and ready for a hack use the intergif program which can extract the single images out of an animated gif. Extract into a temp directory and look how many files you get. http://utter.chaos.org.uk/~pdh/software/intergif/download.htm
或者简单而懒惰并准备好进行黑客攻击的 intergif 程序可以从动画 gif 中提取单个图像。解压到一个临时目录,看看你得到了多少文件。 http://utter.chaos.org.uk/~pdh/software/intergif/download.htm
回答by ecotechie
The ImageMagick function getNumberImages will do this for you. Since it returns the number of images in the object. Imagick::getNumberImages
ImageMagick 函数 getNumberImages 将为您完成此操作。因为它返回对象中的图像数量。Imagick::getNumberImages
<?php
$image = new Imagick( YOUR_FILE );
if ( $image->getNumberImages() ) {
echo "It's animated";
}
回答by Jake
see if there is more than one LocalDescriptor are there in the GIF file.
查看 GIF 文件中是否有多个 LocalDescriptor。
回答by Ryan Fau
from PIL import Image
fp = open('1.gif', 'rb')
im = Image.open(fp)
is_gif = bool(im.format and im.format.upper() == 'GIF')