發(fā)布于:2021-02-02 11:00:20
0
132
0
在本文中,我們將討論在Android平臺(tái)上創(chuàng)建動(dòng)畫(huà)gif。如果您想開(kāi)發(fā)像Giphy-Cam或GIF-Maker&GIF-Editor&Video-Maker這樣的應(yīng)用程序,有必要了解在GIF-Maker應(yīng)用程序開(kāi)發(fā)過(guò)程中您會(huì)遇到哪些挑戰(zhàn),以及如何面對(duì)這些挑戰(zhàn)。
為什么安卓會(huì)這么做本機(jī)不支持(動(dòng)畫(huà))GIF?
GIFs在Android上的支持從一開(kāi)始就不是完美的。長(zhǎng)話(huà)短說(shuō):在android8(Oreo)之前,系統(tǒng)本身(因此不考慮任何第三方庫(kù))只支持非動(dòng)畫(huà)gif顯示(對(duì)于動(dòng)畫(huà)gif,只有第一幀顯示為靜態(tài)圖像)。根本不支持編碼。
從android9(Pie)開(kāi)始,可以使用圖像解碼器。它可以產(chǎn)生動(dòng)畫(huà)圖像繪制。不幸的是,這些類(lèi)只是平臺(tái)的一部分,并沒(méi)有被后傳到androidxjetpack,所以現(xiàn)在(2020年6月),只有大約40%的用戶(hù)可以從中受益。
為什么GIF支持這么復(fù)雜?
好吧,但是為什么Android對(duì)GIF的支持這么差呢?嗯,只有谷歌能說(shuō)出真相。然而,我們可以推斷出一些原因
首先,實(shí)現(xiàn)顯示動(dòng)畫(huà)圖像比靜態(tài)圖像要困難得多。其次,編碼(創(chuàng)建新文件)比解碼(讀取和顯示)更困難。所以我們有一個(gè)困難組合!
靜態(tài)圖像與動(dòng)畫(huà)
讓我們先來(lái)看看靜態(tài)圖像(如PNG或JPG)和動(dòng)畫(huà)(如GIF,但GIF也可以不是動(dòng)畫(huà))之間的區(qū)別。 靜態(tài)圖像解碼通常歸結(jié)為獲取輸入(如本地文件或圖像URL)和產(chǎn)生輸出(位圖–一個(gè)二維像素?cái)?shù)組)。在這個(gè)操作之后,一切都取決于UI層,解碼器不需要關(guān)心這個(gè)問(wèn)題。請(qǐng)注意,我們現(xiàn)在考慮的是一個(gè)簡(jiǎn)單的情況—按原樣顯示圖像。像Glide或Coil這樣成熟的圖像解碼庫(kù)具有緩存、轉(zhuǎn)換等附加功能 動(dòng)畫(huà)可以描述為一系列靜態(tài)圖像(幀)。因此解碼過(guò)程包括上述多個(gè)步驟。然而,還有更多的因素需要考慮。首先,我們需要一種計(jì)時(shí)器(時(shí)鐘),它負(fù)責(zé)推進(jìn)時(shí)間(切換到后續(xù)幀)。 這樣的時(shí)鐘需要知道UI生命周期。尤其是當(dāng)用戶(hù)界面不再活躍時(shí)(例如用戶(hù)按下后退按鈕或簡(jiǎn)單地切換到另一個(gè)應(yīng)用程序),它需要被處理掉。 現(xiàn)在,我們說(shuō)到點(diǎn)子上了。正確處理Android UI生命周期對(duì)實(shí)現(xiàn)它的開(kāi)發(fā)人員來(lái)說(shuō)是一個(gè)重大挑戰(zhàn)。Android應(yīng)用程序中的許多錯(cuò)誤和崩潰都是由于不正確的生命周期處理導(dǎo)致的泄漏造成的。就連谷歌最近也不贊成AsyncTask——一個(gè)他們自己發(fā)明并推廣多年的類(lèi)。電影類(lèi),經(jīng)常用于GIF解碼,也曾經(jīng)有一個(gè)漏洞。兩個(gè)月后又發(fā)現(xiàn)了一個(gè)。 編碼與解碼 現(xiàn)在,讓我們深入研究GIF編碼,看看為什么這個(gè)過(guò)程比解碼復(fù)雜得多。主要有兩個(gè)原因。 GIF文件中的圖像數(shù)據(jù)分為幾幀。但是,它們并不總是與物理膠卷相同。讓我們看一下以下動(dòng)畫(huà): 編碼的最有效方法是僅存儲(chǔ)后續(xù)幀的差異: 當(dāng)然,沒(méi)有什么可以像這樣保存完整尺寸的第二幀: 但是,這樣做會(huì)導(dǎo)致GIF文件的整體大小變得更大(而且,如您在下一段中將看到的那樣,顏色的數(shù)量可能會(huì)受到限制)。 請(qǐng)注意,現(xiàn)實(shí)生活中使用的GIF文件通常包含幾十或幾百幀,通常比這個(gè)簡(jiǎn)單示例中的幀大。通常,制作GIF的電影源輸出全尺寸的幀。提取后續(xù)幀之間的差異不是一個(gè)簡(jiǎn)單的問(wèn)題。 絕大多數(shù)當(dāng)前使用的計(jì)算機(jī)和移動(dòng)顯示器(可能包括您正在閱讀本文的顯示器)以及圖像格式(GIF、JPG、PNG等)都使用24位顏色深度。這意味著大約1600萬(wàn)種顏色(平均人眼可以分辨1000萬(wàn)種)。 但是,單個(gè)GIF幀最多只能包含256種不同的顏色。從前面的段落可以看出,GIF動(dòng)畫(huà)的當(dāng)前可見(jiàn)狀態(tài)可能包含許多幀,因此整個(gè)GIF中的顏色數(shù)與單個(gè)幀中的顏色數(shù)不同。 那么,如何將1600萬(wàn)種可能性整合到256個(gè)地方呢?好吧,很難有效地做到這一點(diǎn),但是已經(jīng)開(kāi)發(fā)了許多技術(shù),它們統(tǒng)稱(chēng)為抖動(dòng)。盡管GIF格式已經(jīng)有30多年的歷史了(因此有人可能認(rèn)為我們應(yīng)該對(duì)它的一切都了如指掌),但新的編碼技術(shù)(如禮品網(wǎng))仍在不斷發(fā)展。 GIF編碼是一個(gè)復(fù)雜的操作,它需要在Android設(shè)備上以合理的性能工作。在應(yīng)用程序中創(chuàng)建GIF編碼需要熟練的開(kāi)發(fā)人員,他們知道如何使用本機(jī)開(kāi)發(fā)工具包(NDK)。 如何應(yīng)對(duì)GIF應(yīng)用開(kāi)發(fā)中的障礙? 正如你所見(jiàn),GIF-maker應(yīng)用程序在Android上的開(kāi)發(fā)帶來(lái)了很多問(wèn)題。有沒(méi)有辦法解決這些問(wèn)題?好吧,沒(méi)有銀彈。然而,我們可以找到一些可以進(jìn)一步組合的部分解。 現(xiàn)在,許多著名的第三方庫(kù)(如Glide、Coil)都在處理GIF動(dòng)畫(huà)顯示,但畢加索卻沒(méi)有。對(duì)于更復(fù)雜的操作,例如渲染到OpenGL紋理或更改幀速率,可以使用android gif drawable。 然而,Android上的GIF編碼通常需要一些額外的開(kāi)發(fā)和對(duì)NDK的熟悉。 現(xiàn)成的庫(kù)確實(shí)存在,但可能不是功能齊全(比如gifencoder不支持透明性),或者不再維護(hù)(比如gifencoder)。許多著名的開(kāi)源低級(jí)圖形庫(kù)(如gifsicle或FFmpeg)都可以為Android編譯。甚至還有像mobileffmepeg這樣的包裝器,可以簡(jiǎn)化對(duì)Android的適應(yīng)。 GIF應(yīng)用程序開(kāi)發(fā)-總結(jié) 如您所見(jiàn),很難顯示,甚至更難創(chuàng)建動(dòng)畫(huà)gif。即使是谷歌的開(kāi)發(fā)者也有麻煩。請(qǐng)記住: 為Android開(kāi)發(fā)GIF應(yīng)用程序需要額外的時(shí)間進(jìn)行研究和測(cè)試。 在選擇開(kāi)發(fā)團(tuán)隊(duì)為Android構(gòu)建GIF maker應(yīng)用程序時(shí),請(qǐng)確保他們熟悉Android NDK。 由于這些類(lèi)型的項(xiàng)目不是小菜一碟,因此值得與已經(jīng)有經(jīng)驗(yàn)的團(tuán)隊(duì)合作在創(chuàng)建類(lèi)似的應(yīng)用程序時(shí)。 今天推薦的解決方案明天可能會(huì)過(guò)時(shí)和棄用,因此該應(yīng)用程序可能需要定期維護(hù)。
作者介紹
熱門(mén)博客推薦