發(fā)布于:2021-01-30 11:25:20
0
131
0
在本文中,我們將簡要列出可以幫助您進行GIF文件編碼的庫,這是GIF maker應(yīng)用程序開發(fā)過程中的一個重要部分。請注意,項目在不斷發(fā)展,有些項目遭到否決,有些項目出現(xiàn)了新的項目。
為什么GIF編碼如此復(fù)雜?
似乎用一系列圖像制作GIF文件就像制作一個視頻文件一樣,只是格式不同。好吧,沒有什么比這更離譜了!請記住,GIF格式是在1987年開發(fā)出來的,30多年前,一開始甚至不支持動畫。這就是為什么它有一些限制,使編碼有點困難。
調(diào)色板
最重要的問題是一個GIF幀最多可以包含256種顏色(包括透明的)。在給定時刻可見的快照可能由多個幀組成。這是因為一個幀的大小可能小于整個畫布。另外,幀可以包含透明像素。如果我們想對一個超過256色的幀進行編碼,我們必須對它進行某種變換。有幾種方法可以解決這個問題,其中一些方法也可以結(jié)合使用。
其中之一是抖動。粗略地說,它通過混合更多不同的顏色來模擬中間顏色。你可以在下圖中看到一個例子。請注意,圖像僅由完全黑色和完全白色的像素組成。然而,抖動引入了灰度錯覺。
如果所有的幀都可以存儲(無論是在內(nèi)存中還是以視頻文件的格式),我們可以首先檢查所有幀,檢查使用的顏色和頻率(創(chuàng)建直方圖),并建立一個最佳的調(diào)色板。有幾種方法可以創(chuàng)建這樣的直方圖。例如,F(xiàn)Fmpeg的palettegen過濾器支持3種不同的統(tǒng)計模式。
每個GIF幀可以有自己的調(diào)色板(如果沒有,則使用全局調(diào)色板)。使用單獨的調(diào)色板,我們可以在整個文件中有更多的顏色。但是,多個選項板會消耗額外的存儲空間和解碼時間。根據(jù)動畫長度、畫布大小和用法,它可能有意義,也可能沒有意義。您可以在有關(guān)高質(zhì)量GIF編碼的文章中了解更多信息。
請注意,GIF格式只支持透明性(alpha位-像素可以是完全透明的或完全不透明的),而不支持半透明性(alpha通道-細(xì)粒度透明級別)。這意味著,如果源包含半透明像素,則它們在輸出GIF文件中會顯示為透明或不透明。請看以下圖片:
時間表
每個幀可以有自己的延遲。顯示幀的時間。延遲的測量單位為厘米秒(1個單位=0.01秒)。每秒100幀聽起來不錯。然而,由于GIF解碼通常比視頻(通常是硬件加速)慢,因此引入了限制。最低值(最短延遲)被人為地增加到更高的值。更重要的是,增加后的值通常不是最小值,而是更高的值!
例如,在撰寫本文的環(huán)境中,有效的最小延遲為0.02s。所有較小的延遲都增加到0.01s。請參見下面的動畫:
延遲0.01s的GIF(可以像0.1s一樣可見)
另請參閱動畫GIF最小幀延遲瀏覽器兼容性研究(這也是上述圖片的來源),以了解不同瀏覽器中的更多示例。您可能對web存檔副本感興趣,因為原始網(wǎng)站上的圖像已死亡。選擇最小值不是一件容易的事。
安卓
運行Android的設(shè)備(主要是智能手機和平板電腦)通常比同時使用的PC具有更少的高性能硬件,因此優(yōu)化在這里具有重要意義。這意味著Android應(yīng)用程序中的GIF編碼通常是本地完成的(使用C / C ++和JNI,不要與本地–非混合,非Flutter應(yīng)用程序混淆)。
幸運的是,當(dāng)您在應(yīng)用程序中開發(fā)GIF編碼時,并不總是需要進行如此低級的抽象。最流行的圖像/視頻編碼庫之一是FFmpeg。Android開發(fā)者友好版還沒有正式提供。但是,確實存在一些包裝器。在編寫時,最流行的是移動FFmpeg。當(dāng)您只想從某個輸入源生成GIF時,這樣的東西可能就是您所需要的全部。
如果您想操作一些更特定于GIF的屬性,如單個幀上的處理方法或修改GIF文件元數(shù)據(jù),您可能會對gifsicle感興趣。不幸的是,它既沒有官方的Android綁定,也沒有著名的非官方端口。您需要從源代碼處編譯它。
總結(jié)
GIF編碼不是一個簡單的過程。由于GIF不是為現(xiàn)代動畫設(shè)計的,我們需要借助非常復(fù)雜的技術(shù)來獲得令人滿意的效果。幸運的是,我們不需要從頭開始寫。這個主題非常流行,所以有現(xiàn)成的庫,至少可以用于應(yīng)用程序的低級部分。