ImageMagick 範例 --
動畫基礎
- 索引
-
ImageMagick 範例 前言和索引
-
GIF 動畫和動畫元數據
-
畫面處理方法
-
研究動畫
-
動畫類型
-
循環結束 - 動畫停止運行時
-
零延遲中間畫面
GIF 動畫和動畫元數據
ImageMagick 處理圖像列表輸出的默認方式是生成多頁圖像。但是,對於 GIF 圖像格式,這採用了“GIF 動畫”的特殊形式。
|
![]() |
star_field
”的 shell 腳本。這個腳本是從我生成隨機星場的實驗中發展出來的。屏幕
”alpha 合成將其疊加到我們的圖像(IM 內置的“rose:
”)上,以使用給定的星形圖案使圖像變亮。然後,整個過程將通過 IM 通用 GIF 動畫優化器運行。以上內容可能看起來很複雜,因為它使用了我尚未介紹的一些高級 IM 功能,但結果是一個相對簡單但經過良好優化的三幀動畫。您還可以查看一些使用簡單 shell 腳本為失真動畫創建的更複雜的動畫。還有一些專門為 GIF 動畫創建的額外 IM 設置,了解這些設置是進入 GIF 動畫世界的第一步...-dispose {方法} |
|||
以下圖像應該如何處理 GIF 動畫的先前結果。有效選項為「Undefined 」、「None 」、「Previous 」和「Background 」。 (有關設定的說明,請參見下文) |
|||
-loop {次數} |
GIF 動畫在停止前循環播放圖像序列的次數。 它是一個輸出「圖像寫入」設定,因此可以在命令列的任何位置設定,儘管只會使用最後一個此類設定。 通常預設情況下設定為零(無限循環),但是如果讀入的任何圖像具有不同的值,則此設定將設定為該圖像的值。 因此,我建議您在讀入所有圖像後,在建立 GIF 動畫時始終設定「-loop 」。 如需更多資訊,請參閱下方的循環結束。 |
||
-delay {時間} |
設定在繪製定義此設定後讀入或建立的圖像後暫停的時間延遲(以 1/100 秒為單位)。 您可以通過指定「x 」縮放比例(以每秒滴答數表示)來指定時間延遲的不同縮放比例。 例如,「10x1 」是 10 個 1 秒的滴答聲,而「10x100 」是 10 個百分之一秒的滴答聲。 基本上,「x 」等效於分數「/ 」符號。 例如,如果您指定「1x160 」,則將設定適合每秒 160 幀的延遲。
|
||
-set dispose {方法} |
|||
雖然先前的選項設定將在新建立的圖像或讀入的圖像上設定圖像屬性,但在給出該選項之後,「-set 」選項是一個運算符,它允許您設定圖像屬性在當前圖像序列中已經的所有圖像上。 這允許您在載入或修改圖像後更改整個動畫或僅單個影格的設定。 |
|||
-page {寬}x{高}+{x}+{y} |
|||
這使您可以設定即將讀入的圖像的偏移位置。 由於這是一個設定選項,因此它僅將您提供的幾何形狀應用於設定後面的圖像。 它不會影響已讀入記憶體的圖像。 如果未給出或使用「 x 」高度來定義更大的工作畫布。 只有序列中第一個圖像的寬度和高度頁面設定將用於設定整體 GIF 動畫畫布大小,在最終寫入動畫時,所有其他頁面大小設定都將被忽略。 當讀入 GIF 動畫時,畫布大小將設定為動畫中的所有影格。 MNG 動畫可以儲存影格偏移量,但不能儲存畫布大小。 第一個圖像的大小決定了整個動畫的畫布大小。
|
|||
-repage {w}x{h}+{x}+{y} |
|||
這與「-page 」完全相同,只不過它是一個圖像運算子,而不是一個設定。這表示您可以使用它來更改或重置已讀入內存的圖像或動畫影格的「頁面幾何」。更簡單的「+repage 」形式,只是將當前圖像序列中每個影格中所有圖像的「頁面幾何」重置為零偏移量,以及圖像的實際大小。當您從動畫中提取單個影格時,此操作至關重要(請參閱下面的附加範例)。但是,「+repage 」會破壞存儲在每個圖像中的大量位置信息,因此您可能還應該將此信息提取到單獨的檔案中,以便以後重複使用。請參閱下面的動畫清單信息。 |
重點
不要將尚未完成處理的中間動畫直接保存為 GIF。如果您想以一系列單獨的處理步驟處理動畫,則可以使用 IM 內部格式 MIFF 作為臨時文件格式。我重複一遍...
不要使用 GIF 作為中間文件格式,請改用 MIFF
如果您犯了將其保存為 GIF 的大錯誤,那麼您只會使生成的動畫變得更糟,因為 IM 現在會執行自動顏色量化,以減少存在的顏色數量。不僅如此,它還對每個影格完全獨立於其他所有影格進行了處理,這使得任何進一步的處理,尤其是任何 GIF 優化都變得更加困難。解決這個問題是一個複雜的多層次問題,我們將在下一節動畫優化中進行探討。影格處置方法
建立 GIF 動畫的人首先遇到的問題通常是 "-dispose
" 設定。這一點也不令人意外,因為這是一個複雜的設定。更糟糕的是,許多動畫程式,包括許多網路瀏覽器,並不總是能正確處理 GIF 處置中繼資料設定。然而,使用正確的處置方式可以對動畫的運作和優化產生很大的影響。在 ImageMagick 中,首先要記住的是,幾乎所有特殊的動畫選項都是用於圖像讀取的設定。也就是說,它們會在設定給定後應用於讀入的圖像。"-loop
" 設定是唯一一個通常在動畫完成後、動畫儲存前使用的設定。"-dispose
" 的基本任務是定義圖像在顯示其 "-delay
" 時間後如何被移除。也就是說,您需要在讀取該影格的圖像之前,先給定圖像的 "-dispose
" 和 "-delay
" 設定。但動作是在顯示該圖像後才套用。這有點違反直覺,但在 IM 操作圖像的方式上卻是合理的。如果您記住這一點,您應該不會有任何問題。這些選項的「加號」形式,就像 IM 中的大多數其他設定一樣,會停止將設定應用於任何正在讀入的圖像。這意味著,如果您沒有指定設定,則影格圖像將繼續使用讀入圖像時所用的設定(如果有)。當您想讀入 GIF 動畫以進行進一步處理時,或者當您要將一個 GIF 動畫合併到另一個 GIF 動畫中時(最困難的動畫技術),這一點可能會變得非常重要。處置方式:無- 每個影格依序疊加
GIF 動畫的預設 "-dispose
" 設定是 '未定義
',大多數動畫程式將其視為與 '無
' 處置設定相同。基本上,這會告訴電腦保留此特定影格所疊加的任何內容。或者更準確地說,'不做任何事'。但是請注意,整個畫布總是在動畫序列結束時、循環和重複之前清除。以下是一個標準的「無處置」動畫範例...
|
![]() |
|
![]() |
處置方式:前一張- 保留背景畫布
'前一張
' 處置方法相對簡單。當目前圖像完成後,將畫布恢復到疊加圖像之前的樣子。如果前一個影格圖像也使用 '前一張
' 處置方法,則結果將與該影格之前的結果相同... 等等... 等等... 例如,在此動畫中,每個後續影格在疊加與該影格關聯的圖像之前,都會返回到具有 '無
處置設定的第一個影格。結果是一個背景畫布,其中每個影格圖像僅在其持續時間內被疊加...
|
![]() |
-dispose
」方法是「None
」。這一點很重要,否則「前一個」影格會一直回到第一個影格之前存在的原始空白畫布。另請注意,我在上面的動畫中使用了「-delay
」為「0
」。這表示在將第一個影格疊加到此「背景畫布」上之前不要等待。如果沒有它,你會看到一個短暫的延遲,只顯示畫布圖像,上面沒有任何東西。當然,我仍然需要為後面的圖像設置更長的「-delay
」,否則它們會在眨眼間出現和消失,並且會佔用大量觀看者的 CPU 週期。使用「Previous
」處置方法可能會在某些網頁瀏覽器中出現輕微的閃爍或暫停,尤其是在速度較慢的機器上。雖然現在很少看到這種情況,但閃爍本身仍然存在,我認為這是一個錯誤。有關更多細節,請參閱下面的零延遲影格。很少有動畫使用先前處置類型的動畫,原因是電腦很難優化。問題是電腦應該選擇哪個影格作為背景圖像?對於我們人類來說,很容易找出要使用的最佳圖像,但電腦卻很難決定。動畫中要使用的最佳背景圖像甚至可能不會顯示,例如在當前示例中,因此可能不存在於該動畫的未優化版本中。 處置背景- 清除為背景
雖然前兩種「-dispose
」方法相對簡單,但「Background
」可能是最難理解的。當特定影格的時間延遲結束時,該影格覆蓋的區域將被清除。不是整個畫布,只是被覆蓋的區域。完成後,生成的畫布將傳遞到動畫的下一個影格,由該影格的圖像覆蓋。例如,在這裡,我們只是用下一幀替換每一幀。
|
![]() |
Background
」實際上是如何從動畫顯示中「處置」該影格的。
|
![]() |
Previous
」返回到這些像素清晰的影格。但這依賴於了解動畫序列的歷史記錄,這使得電腦很難優化。![]() ![]() |
有些人認為,這種處置方式不應該將疊加區域清除為透明顏色,而應該將其清除為存儲在 GIF 動畫中的「背景」顏色元數據設置。事實上,舊的「Netscape 」瀏覽器(版本 2 和 3)就是這樣做的。但它也沒有正確實現「Previous 」處置方法。另一方面,初始畫布也應該從格式的「背景」顏色設置,而這一點也沒有做到。但是,所有現代網頁瀏覽器都只會將最後疊加的區域清除為透明,因此這現在已成為公認的做法,也是 IM 現在遵循的做法。 |
![]() ![]() |
在 IM 6.2.6-1 版本之前,IM 的「-coalesce 」和「-deconstruct 」操作無法處理使用「Background 」處置方式來使像素透明的動畫,而所有主流網頁瀏覽器都支援此方式。如需範例和詳細資訊,請參閱動畫錯誤。不過,當沒有套用或打算套用像素清除時,這些函式仍可正常運作。現在,「 -coalesce 」已修正此問題,並建立了「-layers OptimizeFrame 」方法來取代使用「-deconstruct 」作為 GIF 動畫影格最佳化函式。 |
研究動畫
在繼續探討 GIF 動畫的基礎知識、類型、最佳化和處理技巧之前,我們需要一些技巧來研究現有的動畫。識別- 動畫的相關資訊
現在,動畫包含許多封裝在每個個別影格中的資訊。您可以使用預設的 IM「identify
」指令查看其中一些資訊。
![]() ![]() |
如果您沒有看到如上所示的輸出,則表示您的 IM 版本有點舊,您真的應該將已安裝的 ImageMagick 版本升級到最新版本。如果您不這麼做,您將錯過 IM 在處理和控制 GIF 動畫方面的許多新進展。 |
合併- 將動畫分割成影格
現在,如上所述,如果檔案格式允許,ImageMagick 預設會嘗試將多個影像儲存到一個檔案中。不過,如寫入多重影像清單中所述,IM 將允許您使用「+adjoin
」設定來指示它將每個影像儲存為磁碟上的個別影像。例如,這裡我們讀取其中一個 GIF 動畫,並以動畫序列輸出個別的影格影像。如果您要檢查上面的實際影像,您會發現雖然大多數網頁瀏覽器顯示的區域較大,為 100x100,每個子影格都顯示在該區域上。事實上,大多數顯示的實際影像真的只有 32x32 像素,就像前面「identify」指令中顯示的一樣。也就是說,大部分區域只是一個沒有繪製任何內容的畫布,稱為影像的「頁面幾何」或「虛擬畫布」。動畫的第一個影像定義了較大的「畫布」,而每個其他影格則定義了這個較大畫布上的「偏移」位置。這個額外資訊會保留在「+adjoin
」設定儲存的影格中。因此,您可以輕鬆地重建 GIF 動畫。不僅每個個別影格影像中都保留了頁面資訊,而且任何延遲、循環和 GIF 處置設定也都會保留。這表示要重建動畫,您只需要讀取所有影像即可。
|
![]() |
+repage
」選項重設頁面大小和偏移,以移除「虛擬畫布」資訊,只保留實際影像。通常在提取動畫子影格時,您通常也會重置影格的延遲和處置設定,以確保它們不會干擾編輯和顯示。例如,在這裡我移除不需要的虛擬畫布和偏移量,並重置時間延遲和處置。當然,如果您刪除了中繼資料,則需要一些方法來記錄和編輯該資料。請參閱 動畫清單資訊(下方),以獲取提取子影格並儲存動畫中繼資料的指令碼,這些資料可以用於重建動畫。
合併- 完整填滿影格
然而,在典型的動畫中,以子影格的形式檢視動畫通常不是很有用。一方面,高度優化的動畫可以由許多非常小的部分組成,而沒有任何視覺指示說明它們如何組合在一起。它還可能有很多其他的「雜訊」,這些雜訊是為了 壓縮優化 而添加的,以減少動畫的整體檔案大小。例如,僅通過查看動畫的單個子影格,很難弄清楚這個動畫實際上做了什麼。「-coalesce
」操作基本上將影格轉換為在上一個影格被正確 處置 並覆蓋下一個子影格之後動畫應該是什麼樣子。也就是說,它不是一個動畫序列,其中每個影格僅表示對前一個「處置」影格的覆蓋更改。此運算子在每個點創建動畫的完整視圖,有點像真正的電影膠片,而不是動畫序列。這樣的序列稱為 合併動畫,更容易研究、編輯、修改和重新優化。例如,這裡將生成我上面顯示的相同「混亂」動畫序列的蒙太奇,但這次我們將「-coalesce
」序列,以便您可以看到實際發生的情況。
|
![]() |
magick montage
」命令瞭解「-coalesce
」的使用,允許您創建動畫影格的「電影膠片」狀影格,就像上面顯示的那樣。此版本還包含對合併的修復,任何 GIF 動畫作品都應該至少是這個版本(或者最好是最新的版本)。![]() ![]() |
下一個示例部分提供了一種更好的蒙太奇技術來檢查動畫。 |
-dispose
」設置實際上是無關緊要的。然而,為了讓使用者安心,「-coalesce
」運算子會將每個影格的「-dispose
」設置為「無
」或「背景
」,以便合併的影格序列將繼續正確動畫化(如上所示)。![]() ![]() |
具有「背景 」處置的影格表示下一個影格需要至少清除一個或多個像素才能正確顯示。因此,在「 -coalesce 」添加「背景 」處置的動畫中,表示動畫不能保存為簡單的 覆蓋動畫(見下文)。從技術上講,您可以將合併影格序列的所有處置設置為「 背景 」或「上一個 」以生成 清除影格動畫(見下文)。儘管並非所有動畫都能以這種形式很好地優化。 |
-coalesce
」運算子也有一些非動畫用途。請參閱 合併和漸進展平 這些用途的示例。動畫影格蒙太奇- 「gif_anim_montage」指令碼
雖然「+adjoin
」運算子可以讓您從動畫中提取實際圖像,而「-coalesce
」可以讓您看到動畫的結果影格,但这兩種方法都遺漏了很多關於動畫的信息。通過對動畫圖像進行一些非常仔細的操作,您可以顯示影格,以便不僅顯示實際影格,還顯示這些影格在較大畫布上的位置。以下是一種顯示動畫的方法。
magick -dispose Background script_k.gif -alpha set \ -compose Copy -bordercolor black -border 1x1 -compose Over \ -coalesce -bordercolor none -frame 4x4+2+2 \ -bordercolor none -border 2x2 +append script_k_parts.gif |
![[IM Output]](script_k_parts.gif)
gif_anim_montage
」,並將其擴展為還列出動畫中每個影格上方的一些細節。請注意各個影格中使用的時間變化,就像筆從頁面上抬起並重新定位一樣暫停。具有可變時間的動畫可能是一些最有趣的,但也更難處理,您將在後面的 IM 示例頁面中看到。「gif_anim_montage
」腳本還提供了特殊的選項「-u
」,它還會在合併動畫的下方放置一個半透明的副本。這使您可以看到新的子影格如何修改顯示的動畫。當然,這具有半透明的像素,因此需要「PNG」圖像格式,或者您可以使用該腳本提供的許多「背景」選項之一,允許您對結果動畫匯總圖像使用 GIF 甚至 JPEG 格式。其他選項允許您定義要使用的行數或列數,以及設置各種非透明背景,或使用紅色框而不是默認的黑色框。此腳本將在接下來的幾頁 IM 示例中大量使用。歡迎提出建議和意見。動畫清單信息- 用於構建動畫的選項
正如我所提到的,使用「+adjoin
」和「-coalesce
」,以及「+repage
」,都是提取和查看 GIF 動畫的有用方法。但是,它們都在此過程中破壞了有關原始動畫的信息。您可以使用 IM「magick identify
」命令和「-verbose
」選項查看有關幀、時間延遲、幀處理等方面的額外信息。然而,我和大多數其他用戶一樣,發現此命令的輸出過於龐大,而且並非真正可以直接使用。這就是我編寫的另一個特殊 shell 腳本的用武之地。「gif2anim
」腳本將分離動畫的各個幀,但也會準確地找出您需要哪些 IM「magick
」選項才能從這些圖像重建動畫。您可以將「gif2anim
」視為一個動畫反彙編器,它以 IM 選項的形式生成動畫的摘要。例如,讓我們解碼我們一直在使用的動畫示例,以恢復用於創建它的原始「magick
」設置,以及使用的單個圖像……
|
![]() ![]() ![]() ![]() ![]() |
gif2anim
」腳本會對單獨的圖像和「.anim
」選項文件使用相同的基本文件名。因此,上述命令生成的動畫序列文件被命名為「canvas_prev.anim
」,其單獨的幀圖像從「canvas_prev_001.gif
」到「canvas_prev_005.gif
」。如果您更仔細地檢查結果,您會發現它實際上確實設法重新創建了我最初創建此 GIF 動畫時使用的原始選項(請參閱處置先前動畫)。此外,雖然它對實際生成動畫並不重要,但重疊幀的大小和時間也被列為註釋,以便於研究。您可以使用「-l
」標誌將動畫序列選項列在屏幕上,而不是將結果保存到文件中。也就是說,僅輸出動畫序列文件,而不是保存它,或者動畫的單個幀圖像。
gif2anim -l canvas_prev.gif |
給定一個「.anim 」文件和單獨的幀圖像,可以使用補充腳本「anim2gif 」來重建動畫。
|
![]() |
anim2gif
」預設情況下會使用「_anim.gif
」後綴重新創建 GIF 動畫。您可以看到生成的「canvas_prev_anim.gif
」動畫看起來和工作原理與原始動畫完全相同。此腳本只是替換「動畫序列文件」中使用的特殊字符串「BASENAME
」,去除所有註釋,然後將剩餘的轉換選項傳遞給「magick
」命令。換句話說,它將上述文件視為帶有註釋的「轉換」腳本類型。使用特殊字符串的原因是,這允許您指定與「.anim
」文件本身名稱不同的基本文件名。這樣,您可以使用一組完全不同的幀圖像(例如原始圖像的修改版本)從舊動畫中重新創建不同的動畫。這是一個非常有用的功能,將在更複雜的動畫處理中使用。(請參閱並排附加動畫以獲取示例)。與「gif2anim
」一樣,「anim2gif
」腳本也有許多有用的選項,可幫助您處理和修改動畫。稍後將使用其中一些選項。例如,請參閱附加動畫。此外,由於「.anim
」文件是純文本文件,您可以使用它來獲取動畫的解碼圖像,以調整 GIF 的元數據,例如動畫的時間、位置、重複部分,或向動畫添加新幀和圖像。畢竟,這就是我最初編寫這些腳本的原因,早在參與 IM 示例之前。目前,「gif2anim
」對於檢查動畫序列以查看發生了什麼以及幀之間應用的時間安排最為有用。處置圖像- 幀的 GIF 處置形式
此特殊的「-layers
」方法「Dispose
」會顯示在時間延遲結束並套用 GIF 處置方法「但」在覆蓋下一幀影像「之前」該幀的顯示方式。換句話說,這會精確顯示 GIF「-dispose
」方法設定對該幀的實際作用,讓您瞭解動畫究竟出了什麼問題。例如,以下說明在套用個別幀處置方法「後」,我們的三個處置方法範例動畫的顯示方式。請記住,這些動畫中的每一個都包含一個使用「None
」「-dispose
」設定設定的「畫布影像」,然後覆蓋四個較小的影像,然後透過各種 GIF 處置方法處置這些影像。「None
」處置動畫...
magick canvas_none.gif -layers Dispose canvas_none_dispose.gif gif_anim_montage canvas_none_dispose.gif canvas_none_dispose_frames.gif |
![[IM Output]](canvas_none_dispose_frames.gif)
Previous
」處置動畫...
magick canvas_prev.gif -layers Dispose canvas_prev_dispose.gif gif_anim_montage canvas_prev_dispose.gif canvas_prev_dispose_frames.gif |
![[IM Output]](canvas_prev_dispose_frames.gif)
Background
」處置動畫...
magick canvas_bgnd.gif -layers Dispose canvas_bgnd_dispose.gif gif_anim_montage canvas_bgnd_dispose.gif canvas_bgnd_dispose_frames.gif |
![[IM Output]](canvas_bgnd_dispose_frames.gif)
None
」處置,因此將保持不變。重要的是「後續」幀中處置方法的效果。![]() ![]() |
「-layers Dispose 」運算只會產生處置幀的「合併」序列。它不會重設處置設定本身,因此結果可能無法正確製作動畫。若要讓以上動畫正確播放,請將所有處置方法設定為「previous 」或「background 」,或者您可以在儲存之前最佳化動畫。 |
![]() ![]() |
套用 GIF 處置方法後,最後一幀的外觀通常與 GIF 動畫無關,因為整個畫布在動畫重複(循環)之前會完全清除。如果它沒有「循環」而是在動畫序列結束時停止,則不會套用最後一幀的處置。 換句話說,如上所示,最後一幀的外觀(處置後),甚至最後一幀的實際處置設定,對 GIF 動畫「沒有」任何影響。IM 通常會在幀最佳化動畫期間,嘗試找出適當的處置方法時,將其設定為與前一幀相同。 |
解構- 報告幀差異區域
在 ImageMagick 中最佳化動畫的傳統方法是「-deconstruct
」其「-coalesce
」形式,使結果更小且下載和製作動畫的速度更快。「不再建議使用此方法」。您應該改用一般 GIF 最佳化工具。此運算子會取得合併的影像序列(實際顯示時動畫幀的顯示方式),並將第二個和後續影像與前一個影像進行比較。然後,它會將該影像替換為已變更像素的最小矩形區域。任何像素變更(無論是顏色變更(覆蓋)還是清除(擦除))都將計入。這很簡單,對於典型的覆蓋動畫,將會產生該動畫的最佳幀最佳化。然而,覆蓋動畫動畫只使用「None
」處置方法。例如,讓我們以上面產生的合併先前動畫為例,它恰好形成覆蓋動畫,並透過「-deconstruct
」運算子執行它。
|
![]() |
|
![]() ![]() ![]() ![]() |
-deconstruct
」返回了從一個合併幀到下一個合併幀的變化區域。 從而產生一個最佳化的覆蓋動畫,它不需要特殊的處置設定。 這與我開始使用的原始手動生成的動畫相比,還遠遠不夠理想,但它本身就很有用。不幸的是,「-deconstruct 」完全不理解 GIF 動畫「-dispose 」設定。 因此,如果你在一個動畫中嘗試這個,該動畫會從一幀清除到下一幀的像素,例如我們上面建立的「背景處置」動畫(如左圖所示),它將會嚴重失敗。 |
![]() |
在這裡,我們採用剛才顯示的動畫,並透過「-coalesce 」和「-deconstruct 」循環來執行它。
|
![]() |
-deconstruct
」會慢慢地破壞動畫。 基本上,「-deconstruct
」的設計只是為了找出圖像圖層之間的差異。 它從未被設計為正確地最佳化動畫,並且對於需要使用各種處置技術來清除(擦除或使之透明)先前覆蓋的像素的動畫,它將會失敗。 幀比較- 更詳細的幀比較
在 IM v6.2.6-2 中,添加了一些額外的 GIF 幀比較方法。 這些方法在內部是為了正確地最佳化動畫而需要的,但也被認為足以將它們提供給命令行和其他 API 介面。Compare_Any
「-layers
」方法「CompareAny
」實際上與「-deconstruct
」完全相同。 事實上,「-deconstruct
」運算符只是「CompareAny
」方法的功能別名。 讓我們再次看看「背景處置」動畫的「deconstruct」或「CompareAny
」的實際圖像結果。
magick canvas_bgnd.gif -coalesce canvas_bgnd_coal.gif gif_anim_montage canvas_bgnd_coal.gif canvas_bgnd_coal_frames.gif magick canvas_bgnd_coal.gif -layers CompareAny magick compare_any.gif gif_anim_montage compare_any.gif compare_any_frames.gif |
![[IM Output]](canvas_bgnd_coal_frames.gif)


![[IM Output]](compare_any_frames.gif)
Compare_Clear
「-layers
」方法「CompareClear
」將顯示包含從一幀到下一幀需要清除的所有像素的最小矩形區域。
|
![[IM Output]](compare_clear_frames.gif)
-quiet
」設定是為了告訴 IM 不要對這個圖像發出任何警告。 如果後面的所有幀都變成「遺漏」圖像,則 GIF 動畫永遠不會清除像素,並且該動畫可以歸類為覆蓋動畫。 Compare_Overlay
最後一個「-layers
」比較方法「CompareOverlay
」會返回自上一幀以來被覆蓋的像素區域(添加或更改了顏色,但沒有被清除)。
magick canvas_bgnd_coal.gif -layers CompareOverlay magick compare_overlay.gif gif_anim_montage compare_overlay.gif compare_overlay_frames.gif |
![[IM Output]](compare_overlay_frames.gif)
![]() ![]() |
所有 "-layers " 的比較方法,以及 "-deconstruct " 運算子,都不會查看或修改所使用的圖像 GIF 處置方法。結果只是一個圖像列表,預期不會被用作動畫本身。 |
![]() ![]() |
雖然運算子設計用於處理合併的圖像序列,但它們也能夠接受未合併的圖像圖層序列,而不會產生錯誤。 在這種情況下,每個影格在進行比較之前,都會使用「 複製 」Alpha 合成方法疊加到先前疊加的影格上。這種 Alpha 合成方法確保圖層中的任何透明度也會被添加到目標圖像中。如果沒有這個方法,上述方法將無法找到在合併圖像序列中被清除為透明的像素。請注意,這與「 -coalesce 」運算子用於處理顯示 GIF 動畫所需的「處置/疊加」循環時,會使用的更常見「疊加 」合成方法不同。 |
動畫類型
您找到的大多數 GIF 動畫都屬於一些基本類型的動畫。了解這些類型可以讓您了解該動畫是如何從一幀顯示到另一幀的,並且可以讓您在處理和修改動畫時使用捷徑。融合動畫
「合併動畫」基本上是一個圖像序列,顯示了在每個「處置/疊加」循環後,動畫在用戶面前應該呈現的樣子。這些圖像基本上就像您在觀看實際的動畫「膠片」時所看到的那樣。它是任何動畫的簡化且完全未優化的形式。這個命名慣例來自 IM「-coalesce
」運算子的名稱,該運算子用於將 GIF 處置動畫轉換為未優化的「合併動畫」。大多數影片格式(MPEG、AVI 等)實際上也由於其本身的性質而屬於「合併動畫」。然而,這些格式也往往不包含任何透明像素,並且通常在動畫的影格之間具有恆定的時間延遲。合併 GIF 動畫中的任何 GIF 處置設定都沒有任何意義,但是「-coalesce
」運算子會適當地設定處置,以便產生的圖像序列仍然可以作為有效的 GIF 動畫。始終替換從一幀到下一幀的每個像素的影片格式通常可以使用「無
」或「未定義
」的 GIF 處置設定。以下是一個本身也是合併動畫的動畫示例,以及動畫各個影格的「gif_anim_montage
」顯示。
![]() |
![]() |
疊加動畫
「覆蓋動畫」是指動畫的每一幀都只會覆蓋新像素到當前顯示的動畫上。換句話說,在動畫的任何時候,它都不需要將像素清除為透明。個別幀可以包含透明度,可以作為背景,也可以作為其優化的一部分,但它永遠不會將像素清除回透明。當然,如果完全不使用透明度,那麼動畫就可以保證能夠轉換成簡單的覆蓋動畫。這可能是最簡單的幀優化動畫類型,並且不需要客戶端進行特殊處理。顯示給用戶的每一幀都可以簡單地看作是所有先前幀的「扁平化」圖像。任何僅使用「無
」GIF 處置方法的動畫都是「覆蓋動畫」。例如,最後一個示例不僅是「完全合併動畫」,也是「覆蓋動畫」,儘管並非所有此類「完全合併動畫」都是「覆蓋動畫」。您可以通過在合併動畫上使用「比較清除
」圖層方法,並檢查所有第二張和後續圖像是否為「遺漏圖像」,來測試動畫是否可以成為覆蓋動畫。也就是說,不需要從一幀到下一幀清除或擦除任何像素。實際上,如果動畫可以成為覆蓋動畫,而無需修改,則 IM「coalesce
」運算符將僅對所有幀使用「無
」處置方法。如果不是這種情況,則「coalesce
」將至少對某些幀使用了「背景
」處置。然後,這為您提供了另一個「僅覆蓋」功能的測試。覆蓋動畫可以使用透明度,但它們在透明背景上没有任何移動部件。例如,手寫字母「K」的動畫就是一個覆蓋動畫,因為每個部分都只是在透明背景上添加或更改現有部分。它永遠不會向結果圖像添加新的透明度(第一幀除外)。
![]() |
![]() |
![[IM 輸出]](../images/dl_world_anim.gif)
當然,通過需要通過覆蓋原始背景來「擦除」舊部件,這意味著覆蓋的子圖像通常更大,因此 GIF 動畫文件的大小通常也更大。遺憾的是,使用 IM 的優化幀運算符可能會,而且很可能會將「合併覆蓋動畫」變成非「覆蓋動畫」,因為它試圖找到更小的 GIF 文件大小。但是,通過對動畫使用解構而不是使用優化幀,您可以確保動畫保持為簡單的「覆蓋動畫」,但前提是動畫確實是「覆蓋動畫」。如果動畫不是「覆蓋動畫」,則解構操作可能會出現嚴重錯誤(請參閱上面的解構)。憑藉一些人類技能,您仍然可以更好地優化覆蓋動畫,例如使用拆分幀更新,並應用某種形式的壓縮優化,而不會破壞動畫的「僅覆蓋」要求。通常,「覆蓋動畫」完全不顯示透明度(它們可以將其用作優化的一部分,但不會顯示它)。如果沒有顯示透明度,則可以保證動畫是「覆蓋動畫」。為什麼「覆蓋動畫」如此重要?因為有些軟體僅限於這種動畫類型。由於僅執行覆蓋而無需處理透明度或保存上一幀來處理 GIF 處置方法,因此處理起來要簡單得多。此類軟體很少見,但確實存在。
清除畫面動畫
當動畫只使用「前一影像」或「背景」GIF 圖像處理方式時,您會得到一種非常特殊的動畫類型。請注意,如果只使用「背景」處理方式,則動畫的所有幀都會被顯示,然後在下一個幀顯示之前被清除。同樣地,如果只使用「前一影像
」處理方式,動畫總是在顯示下一幀之前返回到最初清除的畫布,從而產生相同的效果。如果您只混合使用這兩種處理方式設定,也會發生同樣的情況。也就是說,只使用這些處理方式的動畫將會擁有完整複製要顯示內容的幀。也就是說,該幀包含了在該時間點要向使用者顯示的所有內容。這並不是說動畫是「完全合併的動畫」。因為子影格可能比動畫的虛擬畫布區域小得多,但該影格之外的所有內容都將被視為透明(或背景),不包含任何重要的東西。例如,看看這個正在奔跑的兔子動畫……
![]() |
![]() |
前一影像
」的,您將在下方看到,這是更合乎邏輯的處理方式設定。然而,所有處理方式設定都可以設定為「背景
」處理方式,或兩者的任何混合,而不會改變最終結果。由於沒有更好的名稱,我將這種動畫稱為「已清除影格動畫」,但我還看到它被稱為「前一影像或背景處理動畫」。只有當動畫中至少有一個非空白影格使用「無
」或「未定義
」(相同含義)處理方式時,動畫才不是這種類型。這種動畫非常特別,因為它可以處理動畫序列中任何數量的透明度清除,這與覆蓋動畫不同。但它也可以非常快速地覆蓋到任何靜態背景圖像上。為此,我們需要稍微收緊「已清除影格動畫」的定義。具體來說,我們需要確保所有處理方式都設定為「前一影像
」(在我們的範例中已經是這樣了)。如果這樣做了,那麼您就可以在背景下方預先添加一個圖像(延遲為零)。例如,讓我們把兔子放在草地上……
|
![]() |
前一影像
」處理方式是已清除影格動畫的首選處理方式的原因。與僅是 GIF 動畫特殊子集的覆蓋動畫不同,所有動畫都可以另存為已清除影格動畫。只需合併動畫,並選擇性地修剪任何周圍的透明邊緣以優化影格,然後重設處理方式。
magick any_animation.gif -coalesce -trim \ -set dispose previous cleared_frame_animation.gif |
您甚至可以在該背景上重新定位動畫……
|
![]() |
然而,以這種方式為 GIF 動畫添加背景會產生一個問題。如果您查看前面的範例,您可能會注意到在快速移動的動畫中出現明顯且令人不安的停頓。也就是說,當動畫循環播放並重新載入背景圖片時,兔子會暫時消失。(請參閱零延遲影格中的註釋)雖然這對於使用此技術的應用程式來說不是問題,因為它們只是不顯示「中間」影格,用於將動畫符號添加到顯示的物件。因此,如果您要為 GIF 動畫添加非透明背景,則通常最好將簡單的清除影格動畫轉換為覆蓋動畫。也就是將背景添加到動畫的每個影格,而不是給予初始畫布。您可以通過以下任一方法來做到這一點,合併上述動畫,然後刪除零延遲背景影格,或圖層合成原始動畫到靜態背景。舉例來說...
|
![]() |
![[IM Output]](bunny_bgnd_frames.gif)
![]() ![]() |
IM 論壇成員el_supremo(皮特)貢獻了一個 MagickWand 等效腳本,清除影格到背景範例。 IM 論壇在 MagickWand 中創建清除影格 GIF 動畫中也詳細討論了此範例。 |
混合處理動畫- 多背景動畫
沒有什麼可以阻止您在單個 GIF 動畫中混合使用各種處置方法。事實上,為清除影格動畫添加背景正是這樣做的。對我們人類來說,混合使用處置方法並非如此簡單,但這樣做可以讓您生成一些非常複雜的動畫顯示。一般來說,它們是作為特定動畫的自動影格優化的一部分而創建的。請記住,結果不能像以前的動畫類型那樣直接用於特定目的。事實上,如果某些 GIF 處理程序無法正確處理「混合處置動畫」,請不要感到驚訝。這包括一些可用的 GIF 優化器。「混合處置動畫」的一個典型例子是一個小的移動物件,它會導致動畫背景發生一些半永久性但暫時靜態的變化。球擊中槓桿就是一個例子。Simple Example wanted類似地,涉及較大透明顯示器上的兩個非常小的移動物件的動畫只能通過混合處置技術來很好地優化,以便每個物件都使用單獨的動畫影格移動。
FUTURE, A more complex animation for study. * Start with a semi-transparent canvas * run a little 'previous' disposal * leave one frame as a new 'canvas' * more previous animations * erase that 'addition' using a 'background' disposal set as new canvas * continue back to start point. This animation should thoroughly test out not only IM disposal methods but also various browser disposal methods.如果您想貢獻此類動畫的 IM 範例,您可以在此處獲得您的姓名和主頁連結!
循環結束- 動畫停止時
通常認為不要讓動畫永遠循環播放是一個好主意,因為客戶端機器必須在動畫仍在播放時持續工作。因此,最好考慮一下您的動畫實際循環播放的次數。基本上..
為您的動畫添加循環限制(如果可行)
對於網頁頂部用作 logo 的大型動畫來說尤其如此。根據動畫運行的總時間,對於大型 logo 來說,10 到 30 個循環通常就足夠了。您應該為所有此類動畫添加循環限制,以便為您的用戶著想。「-loop
」儲存設定為 0 表示永遠循環。對於小型動畫,這通常是慣用的做法,而且沒有問題。然而,當動畫達到某個內部循環限制(通常為 256 個循環)時,某些瀏覽器會強制停止。對於 IM 範例,我通常使用「0」的「-loop
」儲存設定,表示「永遠循環」,因為動畫可以出現在頁面的任何位置。這意味著從用戶載入頁面到他們最終查看和閱讀特定 GIF 動畫之間可能需要一些時間。如果我確實使用了較少的「循環」次數,則動畫將不再執行其應演示的內容,從而失去其效果。對於頂級 Flash 頁面上的大型動畫,可以使用「-loop
」為「1」(一般的 GIF 動畫預設值)。這表示僅執行動畫一次,然後停止。這就引出了一個至關重要的問題.. 在哪裡停止? 一些瀏覽器(例如舊的「Netscape
」瀏覽器)會重新顯示動畫的第一幀。然而,大多數現代瀏覽器只會停留在最後一幀,而忽略該幀無用的 處置 設定。然而,特定應用程序的功能取決於應用程序,因為沒有真正的標準。實際上,即使是「循環」中繼資料的使用本身也不是標準的,只是舊的「Netscape
」瀏覽器實現的功能,並且所有後來的瀏覽器都複製了該功能。因此,如果您希望動畫停留在某個特定幀上(例如,顯示公司名稱或 logo 的幀),那麼最好將該幀設為動畫的第一幀和最後一幀。但是,其中一幀應設置為「零延遲」,以免影響動畫的整體循環時間長度。所以總結一下...
如果循環受限,請將「停止」幀添加為第一幀和最後一幀。
零延遲中間幀
關於 已清除的幀動畫,我們已經看到了使用「零延遲」幀的情況。我還使用它們來解釋 先前和背景處置。這些特殊幀實際上比人們想像的要普遍得多。它們不僅代表了將背景「畫布」添加到動畫的方法(例如我上面使用它們的方法)。但它們也是一些更複雜的 幀最佳化 技術(例如 幀加倍 和 拆分幀更新)的必需品。另一個(非常古老的 PNG 格式之前的)用途是允許您創建包含超過 256 色限制的靜態 GIF 圖像!也就是說,每一幀提供 256 種顏色,下一幀提供下一組 256 種顏色,所有顏色都設置為零延遲,並且最後沒有循環。感謝 TLUL 在討論 創建未量化的 GIF 中指出了這一點。這些「零延遲中間幀」並非要顯示給用戶。它們僅用於在 GIF 圖像中創建特殊效果,否則這些效果是不可能的,或者比沒有它們的效果更好。總之...
零延遲幀是中間幀,
它們不應顯示給用戶。
ImageMagick 不僅會在其自動「OptimizePlus」的一部分中為動畫創建此類影格,而且還提供了一種使用「RemoveZero」圖層方法將其刪除的方法。請注意它們,因為它們通常會使您處理動畫變得複雜。好吧,它們很重要,那又怎樣?因為許多應用程式不喜歡它們,或者處理不當。出於某種原因,即使您有目的地將它們添加到動畫中,它們也會將「零延遲影格」視為一件壞事。以下是我知道或被告知會「做錯事」的應用程式摘要...它們不應顯示給用戶。
Gimp | 不會保存「零延遲影格」,它們始終會對任何具有零時間延遲的影格添加最小時間延遲。 :-( |
FireFox | 會在此類影格上給予輕微的非零暫停。這大概是為了讓完全沒有時間延遲的動畫不會耗盡所有電腦的 CPU 週期。但是如果動畫的整體顯示時間不為零,「firefox 」仍然不會放寬該限制。 |
Internet Explorer | 具有 6 厘秒的最小時間延遲,並且會忽略任何小於此值的延遲。如果任何圖像影格超出第一個影格設置的動畫範圍,Internet Explorer 版本 8 也會失敗(立即重新啟動循環)。我將此歸類為一個主要錯誤。 |
永遠不要保存完全沒有「延遲」的 GIF(循環)動畫
這樣做是非常糟糕的做法,也是上述大多數「有錯誤的」應用程式按其方式而不是應有方式運作的原因。如果您看到它們,請向所有者投訴。還要向應用程式開發人員投訴,以便他們正確處理零延遲影格。即使這意味著根本不顯示該影格,而只是將它們用作顯示下一影格的準備。畢竟它們在螢幕上的時間為*零*!