原文首發(fā)于我的個人博客網(wǎng)站,歡迎訪問就轧,轉(zhuǎn)載請注明出處
本文介紹在 Android
平臺下合成 GIF
的方法跌捆,查閱資料的過程中發(fā)現(xiàn)大致有兩種方案亡哄。
使用
giflen
(一個C
的合成gif
的庫) 進行gif
合成。使用
java
層的GifEncoder
枣抱、LZWEncoder
熔吗、NeuQuant
來進行gif
合成。
當然二者都是基于 LZW
算法佳晶,簡單測試的結(jié)果是桅狠,速度上差不多,由于對 C
不是很擅長轿秧,因此我選擇了 java
層進行合成的方法中跌,但是兩種方法速度上都是 很慢很慢 ??。
因此本文還將會使用多線程獨立編碼的方法來進行優(yōu)化淤刃,每幀圖片并行編碼晒他,加快合成速度,現(xiàn)在的成果是 600 * 450
的圖片 20
張的話逸贾,時間大約在 12s
左右。
本文相關(guān)源碼在 GitHub - GifMaker
使用 giflen 合成
使用 jni
合成津滞,感興趣的同學可以 google
一下 giflen
這個庫铝侵,這里有一個編譯好的 so
和 jar
文件,以及相關(guān) C
源碼触徐,備份在 GitHub 上咪鲜,有需要的同學可以直接下載使用。經(jīng)過我的簡單嘗試發(fā)現(xiàn)撞鹉,使用 so
合成的速度和 java
合成的速度差不多疟丙,都是慢的要死...
優(yōu)化后的 java 合成
原始的合成方法,真的慢...特別慢鸟雏,簡直不能忍享郊。
原始的合成方法是將每一個 Bitmap
使用 LZWEncoder
進行編碼,由于是一個串行的邏輯孝鹊,后面的圖片需要等待前面的編碼完成才可以繼續(xù)下一張編碼炊琉,優(yōu)化后的邏輯是啟動一個線程池,每張圖片獨立編碼又活,最后在所有圖片編碼完成之后輸出流合并苔咪,輸出到文件中,就完成了 gif
的合成柳骄。
缺點:大量的 Bitmap
持有在內(nèi)存中并行編碼团赏,可能會 OOM
,不過我測試 20 張 450 * 600 的圖片耐薯,暫時沒有出現(xiàn)問題舔清。合成的圖片要求寬高應該是一樣的隘世,當然使用寬高不一致的圖片也不會有問題,但是會優(yōu)先使用第一張的圖片的寬高作為 gif
的寬高鸠踪,出來的圖片就有些尷尬丙者,因此圖片的轉(zhuǎn)換和處理需要在外面完成。
簡單演示
private void composeGif(List<Bitmap> bitmaps) {
String absolutePath = new File(Environment.getExternalStorageDirectory()
, System.currentTimeMillis() + ".gif").getAbsolutePath();
new GifMaker(100, mExecutorService)
.makeGifInThread(bitmaps, absolutePath, new GifMaker.OnGifMakerListener() {
@Override
public void onMakeGifSucceed(String outPath) {
if (!isFinishing()) {
GlideUtils.with(mActivity, outPath).into(mImageView);
}
}
});
}
看一下輸出的結(jié)果营密,20 張大約維持在 12s 左右
I/GifMaker: 完成第10幀,耗時:9.594 s - bitmap [600,450]
I/GifMaker: 完成第11幀,耗時:9.774 s - bitmap [600,450]
I/GifMaker: 完成第18幀,耗時:9.880 s - bitmap [450,600]
I/GifMaker: 完成第9幀,耗時:10.41 s - bitmap [600,450]
I/GifMaker: 完成第17幀,耗時:10.145 s - bitmap [450,600]
I/GifMaker: 完成第16幀,耗時:10.331 s - bitmap [450,600]
I/GifMaker: 完成第6幀,耗時:10.586 s - bitmap [450,600]
I/GifMaker: 完成第5幀,耗時:10.557 s - bitmap [450,600]
I/GifMaker: 完成第8幀,耗時:10.701 s - bitmap [450,600]
I/GifMaker: 完成第15幀,耗時:10.715 s - bitmap [450,600]
I/GifMaker: 完成第4幀,耗時:10.736 s - bitmap [450,600]
I/GifMaker: 完成第1幀,耗時:10.835 s - bitmap [450,600]
I/GifMaker: 完成第19幀,耗時:10.842 s - bitmap [450,600]
I/GifMaker: 完成第13幀,耗時:10.940 s - bitmap [450,600]
I/GifMaker: 完成第0幀,耗時:10.944 s - bitmap [450,600]
I/GifMaker: 完成第14幀,耗時:10.967 s - bitmap [450,600]
I/GifMaker: 完成第3幀,耗時:10.989 s - bitmap [450,600]
I/GifMaker: 完成第12幀,耗時:10.994 s - bitmap [450,600]
I/GifMaker: 完成第2幀,耗時:10.994 s - bitmap [450,600]
I/GifMaker: 完成第7幀,耗時:11.148 s - bitmap [450,600]
I/GifMaker: 合成完成,耗時:11.167 s