2009-09-11 64 views
11

這裏是another question的鏈接我問到我正在研究的同一個項目。我認爲這一點背景會有所幫助。如何以編程方式檢查GIF圖像是否爲動畫?

對於那些懶得爲這個問題打開一個新標籤的人,我會總結一下我在這裏要做的事情:我已經從4scrape下載了約25萬張圖片,我想要通過GIF和找出哪些是動畫或不。我需要以編程的方式來做這件事,因爲我真的不覺得我的靈魂(或我與女友的關係)可以用4chan看幾千個GIF來看看他們是否是動畫。如果你知道4chan的性質,那麼你就知道圖像的性質(即「山雀或GTFO」)。

我知道PHP和Python,但願意探索其他解決方案。在Windows上運行的獨立軟件也可以工作。

非常感謝!

+2

見http://stackoverflow.com/questions/280658/can-i-detect-animated-gifs-using-php-and-gd – 2009-09-11 18:41:21

回答

16

Python和PIL

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

這工作得很好。謝謝! – 2009-09-13 16:45:15

+1

感謝您的提示。 Tiny nit:將圖像恢復爲0可能很重要,因爲即使在「except」塊中,gif.tell()也會返回1,如果我沒有弄錯的話。 – Ben 2011-10-04 00:56:24

+0

函數getIteratorIndex實際上很簡單http://php.net/manual/en/imagick.getiteratorindex.php – arghav 2013-03-15 20:39:18

3

在函數的PHP docs頁面上給出了一些解決方案。

從我讀過的解決方案來看,由於內存要求更加緊湊,這個看起來是最好的。

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

警告!這段代碼中有一個主要的錯誤。 while語句應該包含括號,否則這個函數不會捕獲所有的動畫gif。雖然它會抓住一些(哪個更糟糕,比它失敗的100%還差)。在這個stackoverflow url看到完整和固定的代碼http://stackoverflow.com/questions/280658/can-i-detect-animated-gifs-using-php-and-gd – billmalarky 2011-11-22 05:36:06

+0

事實上,有一個更新版本的這個腳本修復了可能由photoshop cs5動畫gif創建的bug。看到它[這裏](http://www.php.net/manual/en/function.imagecreatefromgif.php#104473) – billmalarky 2011-11-22 05:41:55

+0

@billmalarky我編輯了答案 – Kornel 2014-01-29 23:12:10

7

我從來沒有見過一個程序會告訴你這個。但GIF是一種塊結構格式,您可以檢查指示動畫GIF的塊是否存在於您的文件中。

從以下維基百科文章中指出:在偏移量爲0x30D的GIF文件中的應用程序擴展(即:3字節幻數爲21 FF 0B)塊,隨後爲幻數4E 45 54 53 43 41 50 45 32 9在偏移量0x310處指示該文件的其餘部分包含多個圖像,並且它們應該是動畫的。

真的維基百科文章更好地解釋它,下面提到的格式文檔擴展了Wiki文章。

因此,您可以使用用Python編寫的程序(我多年前使用C解析GIF,它主要是移動文件指針和讀取字節的練習)解析GIF。確定AE是否存在正確的3字節ID,然後是9個字節的幻數。

http://en.wikipedia.org/wiki/Graphics_Interchange_Format#Animated_.gif

另見http://www.martinreddy.net/gfx/2d/GIF87a.txt

另見http://www.martinreddy.net/gfx/2d/GIF89a.txt

對不起,盡我能爲你做。

1

我不是GIF文件格式專家,但這對我來說是一個有趣的問題,所以我仔細研究了一下。只有在動畫gif的位置爲0x310(編輯)且靜態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"; 
     } 
    } 
} 
13

如果你在Linux(或任何ImageMagick系統),你可以使用一個班輪shell腳本和程序identify

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

我知道你說你喜歡PHP和Python,但你也表示你願意探索其他解決方案。 :)

0

試試這個

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 
1

看看是否有一個以上的LocalDescriptor被那裏的GIF文件。

+1

請擴大您的答案。這更像是一條評論。 – 2012-12-21 01:00:23

0
from PIL import Image 
fp = open('1.gif', 'rb') 
im = Image.open(fp) 
is_gif = bool(im.format and im.format.upper() == 'GIF') 
+0

儘管此代碼可能會回答問題,但如果提供 關於_why_和/或_how_的附加上下文,它將回答 該問題將顯着提高其長期值 值。請[編輯]你的答案,添加一些解釋。 – 2016-04-27 12:12:40

相關問題