Как программно проверить, анимирован ли GIF-образ?

Вот ссылка на другой вопрос, который я задал в отношении того же проекта, над которым я работаю. Я думаю, что немного фона будет полезно.

Для тех, кто слишком ленив, чтобы открыть новую вкладку для этого вопроса, я подведу итог тому, что я пытаюсь сделать здесь: я загрузил около 250 000 изображений из 4scrape, и я хочу пройти через GIF и найти, какие из них анимированные или нет. Мне нужно сделать это программно, потому что я действительно не чувствую, что моя душа (или мои отношения с моей девушкой) может использовать, глядя на пару тысяч GIF из 4chan, чтобы увидеть, анимированы они или нет. Если вы знаете природу 4chan, то вы знаете природу изображений (т. Е. «Сиськи или GTFO»).

Я знаю PHP и Python, но хотел бы изучить другие решения. Также будет работать автономная часть программного обеспечения, которая работает в Windows.

Большое спасибо!

С Python и PIL :

from PIL import Image gif = Image.open('path.gif') try: gif.seek(1) except EOFError: isanimated = False else: isanimated = True 

Если вы работаете в Linux (или в любой системе с ImageMagick ), вы можете использовать сценарий оболочки с одним слоем и identify программу:

 identify *.gif | fgrep '.gif[1] ' 

Я знаю, вы сказали, что предпочитаете PHP и Python, но вы также сказали, что готовы исследовать другие решения. 🙂

Я никогда не видел программу, которая расскажет вам об этом. Но GIF является блочным структурированным форматом, и вы можете проверить, присутствует ли в ваших файлах блок, обозначающий анимированный GIF.

Из статьи Википедии, отмеченной ниже: при смещении 0x30D в GIF-файл добавляется расширение приложения (то есть: 3 байта магического номера 21 FF 0B), а затем магическое число 4E 45 54 53 43 41 50 45 32 9at offset 0x310 указывает, что остальные файл содержит несколько изображений, и они должны быть анимированы.

На самом деле статья в Википедии объясняет это лучше, и нижеуказанные документы формата раскрываются в статье Wiki.

Таким образом, вы можете анализировать GIF с помощью программы, написанной на Python (я анализировал GIF, используя C много лет назад, это было главным образом упражнение по перемещению указателя на файл и чтение байтов). Определите, присутствует ли AE с правильным 3-байтовым идентификатором, а затем 9-байтовое магическое число.

См. http://img.ruphp.com/image/Graphics_Interchange_Format

Также см. http://www.martinreddy.net/gfx/2d/GIF87a.txt

Также см. http://www.martinreddy.net/gfx/2d/GIF89a.txt

Извини, что я могу сделать для тебя.

Несколько решений даны на странице документов PHP для функции imagecreatefromgif .

Из решений, которые я прочитал, этот кажется лучшим из-за его более жестких требований к памяти.

 <?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; } ?> 

Прочтите спецификацию GIF89A и извлеките информацию. http://www.w3.org/Graphics/GIF/spec-gif89a.txt

Или легко и лениво и готово к взлому, используйте программу intergif, которая может извлекать отдельные изображения из анимированного gif. Извлеките в каталог temp и посмотрите, сколько файлов вы получите. http://utter.chaos.org.uk/~pdh/software/intergif/download.htm

Я не эксперт в формате файлов GIF, но для меня это интересная проблема, поэтому я немного ее рассмотрел. Это будет работать только в том случае, если всегда верно, что анимированные gifs имеют значение NETSCAPE2.0 в позиции 0x310 (редактировать). И статические gifs не делают (/ edit), что было в моих тестовых файлах. Это 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"; } } } 

посмотрите, есть ли в файле GIF несколько локальных дескрипторов.

попробуй это

 import Image def checkAnimate(): im = Image.open('image.gif') if not im.info['version'].__contains__('GIF'): print "It's not a GIF file" else: if im.info.has_key('duration'): if im.info['duration'] > 0: return True else: return False else: return False 
 from PIL import Image fp = open('1.gif', 'rb') im = Image.open(fp) is_gif = bool(im.format and im.format.upper() == 'GIF')