【移動應(yīng)用開發(fā)技術(shù)】JNI方法實現(xiàn)圖片壓縮(壓縮率極高)_第1頁
【移動應(yīng)用開發(fā)技術(shù)】JNI方法實現(xiàn)圖片壓縮(壓縮率極高)_第2頁
【移動應(yīng)用開發(fā)技術(shù)】JNI方法實現(xiàn)圖片壓縮(壓縮率極高)_第3頁
【移動應(yīng)用開發(fā)技術(shù)】JNI方法實現(xiàn)圖片壓縮(壓縮率極高)_第4頁
【移動應(yīng)用開發(fā)技術(shù)】JNI方法實現(xiàn)圖片壓縮(壓縮率極高)_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

【移動應(yīng)用開發(fā)技術(shù)】JNI方法實現(xiàn)圖片壓縮(壓縮率極高)

前言

直接使用項目或直接復(fù)制libs中的so庫到項目中即可(當前只構(gòu)建了armeabi),需要其他ABI可檢下項目另外使用CMake構(gòu)建即可。結(jié)果預(yù)覽:

效果圖.png

jni_278KB.png

quality_484KB.png

sample_199KB.png

size_238KB.png

原圖大小5.99M~~我們把所有經(jīng)過壓縮的圖片放到同等大小的情況后,很明顯,采樣壓縮跟尺寸壓縮都不是我們想要的結(jié)果,而質(zhì)量壓縮跟JNI壓縮我設(shè)置的質(zhì)量壓縮值都是30,JNI壓縮出來只有278KB,直接質(zhì)量壓縮出來的有484KB,綜合之后,JNI才是綜合最優(yōu)的方式,當然,如果只是頭像,我們設(shè)置可以把配置值設(shè)置得更小,圖片就更小。為什么iPhone手機圖片的質(zhì)量比Android的好?

首先了解兩個圖像處理庫:libjpeg、Skia。Skia:圖像處理引擎,Google在Android系統(tǒng)上就是采用Skia,它是基于libjpeg的二次封裝,Google在很多其它產(chǎn)品也使用了這個庫,比如Chorme,F(xiàn)irefox等等。libjpeg:早期的圖像處理引擎,用于PC端。官方文檔可以看到libjpeg.doc這樣一段話:

booleanoptimize_coding

TRUEcausesthecompressortocomputeoptimalHuffmancodingtables

fortheimage.Thisrequiresanextrapassoverthedataand

thereforecostsagooddealofspaceandtime.Thedefaultis

FALSE,whichtellsthecompressortousethesuppliedordefault

Huffmantables.Inmostcasesoptimaltablessaveonlyafewpercent

offilesizecomparedtothedefaulttables.Notethatwhenthisis

TRUE,youneednotsupplyHuffmantablesatall,andanyyoudo

supplywillbeoverwritten.

booleanoptimize_coding

TRUEcausesthecompressortocomputeoptimalHuffmancodingtables

fortheimage.Thisrequiresanextrapassoverthedataand

thereforecostsagooddealofspaceandtime.Thedefaultis

FALSE,whichtellsthecompressortousethesuppliedordefault

Huffmantables.Inmostcasesoptimaltablessaveonlyafewpercent

offilesizecomparedtothedefaulttables.Notethatwhenthisis

TRUE,youneednotsupplyHuffmantablesatall,andanyyoudo

supplywillbeoverwritten.

booleanoptimize_coding:

為什么使用最優(yōu)哈夫曼編碼表可以節(jié)省圖像文件很大的比例大小呢?

哈夫曼樹和哈夫曼編碼當樹中的節(jié)點被賦予一個表示某種意義的數(shù)值,我們稱之為該節(jié)點的權(quán)。從樹的根節(jié)點到任意節(jié)點的路徑長度(經(jīng)過的邊數(shù))與該節(jié)點上權(quán)值的乘積稱為該節(jié)點的帶權(quán)路徑長度。樹中所有葉節(jié)點的帶權(quán)路徑長度之和稱為該樹的帶權(quán)路徑長度(WPL)。當帶權(quán)路徑長度最小的二叉樹被稱為哈夫曼樹,也成為最優(yōu)二叉樹。如下圖所示,有三課二叉樹,每個樹都有四個葉子節(jié)點a,b,c,d,分別取帶權(quán)7,5,2,4。他們的帶權(quán)路徑長度分別為(a)WPL=7x2+5x2+2x2+4x2=36(b)WPL=2X1+4X2+7X3+5X3=46(c)WPL=7x1+5x2+2x3+4x3=35節(jié)點如果像c中的方式分布的話,WPL能取最小值(可證明),我們稱為哈夫曼樹。哈夫曼樹構(gòu)造

哈夫曼樹在構(gòu)造時每次從備選節(jié)點中挑出兩個權(quán)值最小的節(jié)點進行構(gòu)造,每次構(gòu)造完成后會生成新的節(jié)點,將構(gòu)造的節(jié)點從備選節(jié)點中刪除并將新產(chǎn)生的節(jié)點加入到備選節(jié)點中。新產(chǎn)生的節(jié)點權(quán)值為參與構(gòu)造的兩個節(jié)點權(quán)值之和。舉例如下:哈夫曼樹應(yīng)用

在處理字符串序列時,如果對每個字符串采用相同的二進制位來表示,則稱這種編碼方式為定長編碼。若允許對不同的字符采用不等長的二進制位進行表示,那么這種方式稱為可變長編碼。可變長編碼其特點是對使用頻率高的字符采用短編碼,而對使用頻率低的字符則采用長編碼的方式。這樣我們就可以減少數(shù)據(jù)的存儲空間,從而起到壓縮數(shù)據(jù)的效果。而通過哈夫曼樹形成的哈夫曼編碼是一種的有效的數(shù)據(jù)壓縮編碼。如果沒有一個編碼是另一個編碼的前綴,則稱這樣的編碼為前綴編碼。如0,101和100是前綴編碼。由前綴碼形成的序列可以被唯一的組成一個字符串序列。如00101100可以被唯一的分析為0,0,101和100。示例:我們對一個字符串進行統(tǒng)計發(fā)現(xiàn)a-f出現(xiàn)的頻率分別為a:45,b:13,c:12,d:16,e:9,f:5,我們對該字符串進行采用哈夫曼編碼進行存儲。WPL=1x45+3x(13+12+16)+4x(5+9)=224這樣算下來使用224二進制位就可以將該字符串存儲起來,因為哈夫曼碼是前綴碼,所以可以唯一的還原出原來的字符序列。如果我們每個字符使用3位進行存儲(至少3位),那么需要300bit才能將該字符串存儲下。其次了解下libjpeg使用哈夫曼編碼是對圖片上的每個像素(ARGB)進行編碼,比如

ARGB(每個顏色通道取值范圍0-255)的編碼分別是:

A:001

R:010

G:011

B:100

A:001

R:010

G:011

B:100

如果采用定長,那一個圖片下來一個人像素就是001010011100...

如果我們使用可變長編碼方式,遍歷、再嵌套遍歷,再嵌套遍歷每一個像素來獲取前綴編碼(沒錯,這個運算過程很大,而且臨時變量內(nèi)存也需要很大,但相對于今天的手機CPU來說,soeasy),我們大致可以得到這樣的編碼:

A:01

R:10

G:11

B:100

A:01

R:10

G:11

B:100

那一個圖片下來一個人像素就是011011100...編碼長度的優(yōu)化后,接下來干的事就是計算權(quán)重以及每個顏色通道對應(yīng)的編碼的出現(xiàn)頻次構(gòu)建哈夫曼樹了,這里就參考上面的圖片了。通過上面的介紹,可以知道最優(yōu)哈夫曼編碼其實是使用了可變長編碼方式,而默認的哈夫曼編碼使用了定長編碼方式,因此需要更多的存儲空間,呈現(xiàn)出來的手機圖片自然會大很大。libjpeg把optimize_coding參數(shù)默認設(shè)置為FALSE是因為10多年前的Android手機CPU跟內(nèi)存都非常吃緊,所以當年沒有設(shè)置為TRUE。如今的手機CPU跟內(nèi)存都“起飛了”,Goolge的Skia圖像處理引擎卻還是使用optimize_coding的默認值FALSE。我們無法修改系統(tǒng)Skia的這個參數(shù)值,所以只能默默忍受size很大的圖像文件。經(jīng)過大量圖像壓縮測試結(jié)果,得到兩個結(jié)論:

1.圖片壓縮到相同的質(zhì)量,F(xiàn)ALSE所產(chǎn)出的圖像文件大小是TRUE的5-10倍。

2.圖片壓縮到相同的質(zhì)量,Android所產(chǎn)出的圖像文件大小比iOS也是大5-10倍。所以,通過使用libjpeg編譯自己的nativelibrary修改optimize_coding參數(shù)的值,達圖像質(zhì)量相同,所產(chǎn)出的圖像卻能節(jié)省5-10倍空間大小的效果。實現(xiàn)的步驟:

1.構(gòu)建libjpeg的so庫

到官方下載對應(yīng)自己電腦系統(tǒng)類型的壓縮包,創(chuàng)建Android項目導(dǎo)入壓縮包里頭的xx.h、xx.c文件構(gòu)建so庫。bither/bither-android-lib已經(jīng)做了這個工作,因此我們只需直接拿他的libjpegbither.so即可。2.導(dǎo)入libjpeg的聲明頭文件,因為步驟1的libjpegbither.so是對這些頭文件的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論