Android中圖片壓縮分析(下)

文章首發(fā)QQ音樂技術(shù)公眾號(hào):

https://mp.weixin.qq.com/s/H9Tz1n4O2-Aawgu7p-XL5w

一勋磕、Android 尺寸壓縮邏輯

針對(duì)圖片尺寸的修改其實(shí)就是一個(gè)圖像重新采樣的過程揍障,放大圖像稱為上采樣(upsamping)啤月,縮小圖像稱為下采樣(downsampling),這里我們重點(diǎn)討論下采樣避消。

在 Android 中圖片重采樣提供了兩種方法低滩,一種叫做鄰近采樣(Nearest Neighbour Resampling),另一種叫做雙線性采樣(Bilinear Resampling)岩喷。

除了 Android 中這兩種常用的重采樣方法之外,還有另外比較常見的兩種:雙立方/雙三次采樣(Bicubic Resampling)Lanczos Resampling监憎。除此之外纱意,還有一些其他個(gè)人或機(jī)構(gòu)發(fā)明的算法 Hermite ResamplingBell Resampling鲸阔,Mitchell Resampling偷霉。我們這里著重介紹前面提到的四種采樣方法。

二褐筛、鄰近采樣(Nearest Neighbour Resampling)

Nearest Neighbour Resampling(鄰近采樣)类少,是 Android 中常用的壓縮方法之一,我們先來看看在 Android 中使用鄰近采樣的示例代碼:

BitmapFactory.Options options = new BitmapFactory.Options();
//或者 inDensity 搭配 inTargetDensity 使用渔扎,算法和 inSampleSize 一樣
options.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/test.png");
Bitmap compress = BitmapFactory.decodeFile("/sdcard/test.png", options);

來看看鄰近采樣的圖片效果:

原圖

  
  


處理之后的圖片

原圖是每個(gè)像素紅綠相間的圖片硫狞,可以看到處理之后的圖片已經(jīng)完全變成了綠色,接著我們來看看 inSampleSzie 的官方描述:

If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory. The sample size is the number of pixels in either dimension that correspond to a single pixel in the decoded bitmap. For example, inSampleSize == 4 returns an image that is 1/4 the width/height of the original, and 1/16 the number of pixels. Any value <= 1 is treated the same as 1. Note: the decoder uses a final value based on powers of 2, any other value will be rounded down to the nearest power of 2.

從官方的解釋中我們可以看到 x(x 為 2 的倍數(shù))個(gè)像素最后對(duì)應(yīng)一個(gè)像素晃痴,由于采樣率設(shè)置為 1/2残吩,所以是兩個(gè)像素生成一個(gè)像素。鄰近采樣的方式比較粗暴倘核,直接選擇其中的一個(gè)像素作為生成像素泣侮,另一個(gè)像素直接拋棄,這樣就造成了圖片變成了純綠色紧唱,也就是紅色像素被拋棄活尊。

鄰近采樣采用的算法叫做鄰近點(diǎn)插值算法。

三漏益、雙線性采樣(Bilinear Resampling)

雙線性采樣(Bilinear Resampling)在 Android 中的使用方式一般有兩種:

Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/test.png");
Bitmap compress = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth()/2, bitmap.getHeight()/2, true);

或者直接使用 matrix 進(jìn)行縮放

Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/test.png");
Matrix matrix = new Matrix();
matrix.setScale(0.5f, 0.5f);
bm = Bitmap.createBitmap(bitmap, 0, 0, bit.getWidth(), bit.getHeight(), matrix, true);

看源碼可以知道 createScaledBitmap 函數(shù)最終也是使用第二種方式的 matrix 進(jìn)行縮放蛹锰,我們來看看雙線性采樣的表現(xiàn):

原圖
處理之后的圖片

可以看到處理之后的圖片不是像鄰近采樣一樣純粹的一種顏色,而是兩種顏色的混合遭庶。雙線性采樣使用的是雙線性內(nèi)插值算法宁仔,這個(gè)算法不像鄰近點(diǎn)插值算法一樣,直接粗暴的選擇一個(gè)像素峦睡,而是參考了源像素相應(yīng)位置周圍 2x2 個(gè)點(diǎn)的值翎苫,根據(jù)相對(duì)位置取對(duì)應(yīng)的權(quán)重权埠,經(jīng)過計(jì)算之后得到目標(biāo)圖像。

雙線性內(nèi)插值算法在圖像的縮放處理中具有抗鋸齒功能, 是最簡(jiǎn)單和常見的圖像縮放算法煎谍,當(dāng)對(duì)相鄰 2x2 個(gè)像素點(diǎn)采用雙線性內(nèi)插值算法時(shí)攘蔽,所得表面在鄰域處是吻合的,但斜率不吻合呐粘,并且雙線性內(nèi)插值算法的平滑作用可能使得圖像的細(xì)節(jié)產(chǎn)生退化满俗,這種現(xiàn)象在上采樣時(shí)尤其明顯。

四作岖、鄰近采樣和雙線性采樣對(duì)比

我們這里來對(duì)比一下這兩種 Android 中經(jīng)常用到的圖片尺寸壓縮方法唆垃。

鄰近采樣的方式是最快的,因?yàn)樗苯舆x擇其中一個(gè)像素作為生成像素痘儡,但是生成的圖片可能會(huì)相對(duì)比較失真辕万,產(chǎn)生比較明顯的鋸齒,最具有代表性的就是處理文字比較多的圖片在展示效果上的差別沉删,對(duì)比:

原圖:
原圖

鄰近采樣:
鄰近采樣

雙線性采樣:
雙線性采樣

這個(gè)對(duì)比就非常直觀了渐尿,鄰近采樣字的顯示失真對(duì)比雙線性采樣來說要嚴(yán)重很多。

五矾瑰、雙立方/雙三次采樣(Bicubic Resampling)

雙立方/雙三次采樣使用的是雙立方/雙三次插值算法砖茸。鄰近點(diǎn)插值算法的目標(biāo)像素值由源圖上單個(gè)像素決定,雙線性內(nèi)插值算法由源像素某點(diǎn)周圍 2x2 個(gè)像素點(diǎn)按一定權(quán)重獲得殴穴,而雙立方/雙三次插值算法更進(jìn)一步參考了源像素某點(diǎn)周圍 4x4 個(gè)像素凉夯。

這個(gè)算法在 Android 中并沒有原生支持,如果需要使用推正,可以通過手動(dòng)編寫算法或者引用第三方算法庫恍涂,幸運(yùn)的是這個(gè)算法在 ffmpeg 中已經(jīng)給到了支持,具體的實(shí)現(xiàn)在 libswscale/swscale.c 文件中:FFmpeg Scaler Documentation植榕。

雙立方/雙三次插值算法經(jīng)常用于圖像或者視頻的縮放再沧,它能比雙線性內(nèi)插值算法保留更好的細(xì)節(jié)質(zhì)量。我們看看這個(gè)算法的實(shí)際表現(xiàn)和與雙線性內(nèi)插值算法的下采樣對(duì)比:

原圖:
下采樣--原圖

雙三次采樣:
下采樣--雙三次采樣

雙線性采樣:
下采樣--雙線性采樣

就下采樣來說尊残,兩者表現(xiàn)很相近炒瘸,肉眼可見的差距不大,接下來比較一下這兩種算法的上采樣實(shí)際表現(xiàn):

原圖:
上采樣--原圖

雙三次采樣:
上采樣--雙三次采樣

雙線性采樣:
上采樣--雙線性采樣

這兩種算法的上采樣結(jié)果我們還是可以看見較為明顯的差距寝衫,雙立方/雙三次采樣的鋸齒是要小一些顷扩。

雙立方/雙三次插值算法在平時(shí)的軟件中是很常用的一種圖片處理算法,但是這個(gè)算法有一個(gè)缺點(diǎn)就是計(jì)算量會(huì)相對(duì)比較大慰毅,是前三種算法中計(jì)算量最大的隘截,軟件 photoshop 中的圖片縮放功能使用的就是這個(gè)算法。

六、Lanczos Resampling

Lanczos 采樣和 Lanczos 過濾是 Lanczos 算法的兩種常見應(yīng)用婶芭,它可以用作低通濾波器或者用于平滑地在采樣之間插入數(shù)字信號(hào)东臀,Lanczos 采樣一般用來增加數(shù)字信號(hào)的采樣率,或者間隔采樣來降低采樣率犀农。

Lanczos 采樣使用的 Lanczos 算法也可以用來作為圖片的縮放惰赋,Lanczos 算法和雙三次插值算法都是使用卷積核來通過輸入像素計(jì)算輸出像素,只不過在算法表現(xiàn)上稍有不同呵哨。關(guān)于卷積核的介紹赁濒,這里給一張簡(jiǎn)單的圖片幫助大家理解:

圖像卷積

Lanczos 從算法角度講理論上會(huì)比雙三次/雙立方插值算法更好一點(diǎn),先來看看它和雙三次/雙立方采樣的圖片下采樣對(duì)比:

原圖:
下采樣--原圖

Lanczos 采樣:
下采樣--Lanczos 采樣

雙三次采樣:
下采樣--雙三次采樣

基本看不出差別孟害,然后是這兩種算法的上采樣對(duì)比:

原圖:
上采樣--原圖

Lanczos 采樣:
上采樣--Lanczos 采樣

雙三次采樣:
上采樣--雙三次采樣

這兩種算法的上下采樣結(jié)果從肉眼上看差距很小拒炎,但是從理論上來說 Lanczos 算法處理出來的圖片應(yīng)該是更加平滑少鋸齒的。

同樣的纹坐,Lanczos 算法在 ffmpeg 的 libswscale/swscale.c 中也有實(shí)現(xiàn)枝冀。其實(shí)不光 Lanczos 和上面的三種算法,ffmpeg 還提供了其他的圖像重采樣方法耘子,諸如 area averagingGaussian 等等球切,通過編譯好的 ffmpeg 庫調(diào)用這些算法處理圖片的命令如下:

ffmpeg -s 600x500 -i input.jpg -s 300x250 -sws_flags lanczos lanczos.jpg

-sws_flags 參數(shù)根據(jù)采樣算法可以選擇 bilinear/bicubic/lanczos 等等谷誓。

七、四種算法對(duì)二值化圖片的處理表現(xiàn)

這四種圖片重采樣算法在處理二值化圖片上面的表現(xiàn)差異較大吨凑,我們先看看下采樣的對(duì)比:

原圖:
下采樣--原圖

鄰近采樣:
下采樣--鄰近采樣

雙線性采樣:
下采樣--雙線性采樣

雙三次采樣:
下采樣--雙三次采樣

Lanczos 采樣:
下采樣--Lanczos 采樣

下采樣的對(duì)比一目了然捍歪,從上到下的圖像表現(xiàn)效果逐漸變優(yōu),Lanczos 算法處理后的圖像質(zhì)量屬于最優(yōu)鸵钝,接著我們看看這四種算法的上采樣對(duì)比:

原圖:
上采樣--原圖

鄰近采樣:
上采樣--鄰近采樣

雙線性采樣:
上采樣--雙線性采樣

雙三次采樣:
上采樣--雙三次采樣

Lanczos 采樣:
上采樣--Lanczos 采樣

從圖像質(zhì)量上來看糙臼,和下采樣結(jié)果一致,鄰近采樣效果較差恩商,依次往下效果變優(yōu)变逃,Lanczos 效果最優(yōu)。

八怠堪、總結(jié)

上面主要介紹了常見的四種圖像重采樣算法揽乱,在 Android 中,前兩種采樣方法根據(jù)實(shí)際情況去選擇即可粟矿,如果對(duì)時(shí)間要求不高凰棉,傾向于使用雙線性采樣去縮放圖片。如果對(duì)圖片質(zhì)量要求很高陌粹,雙線性采樣也已經(jīng)無法滿足要求撒犀,則可以考慮引入另外幾種算法去處理圖片,但是同時(shí)需要注意的是后面兩種算法使用的都是卷積核去計(jì)算生成像素,計(jì)算量會(huì)相對(duì)比較大或舞,Lanczos 的計(jì)算量則是最大荆姆,在實(shí)際開發(fā)過程中根據(jù)需求進(jìn)行算法的選擇即可。

九嚷那、參考

  1. 圖像卷積與濾波的一些知識(shí)點(diǎn)
  2. TUTORIAL: IMAGE RESCALING
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末胞枕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子魏宽,更是在濱河造成了極大的恐慌腐泻,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件队询,死亡現(xiàn)場(chǎng)離奇詭異派桩,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蚌斩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門铆惑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人送膳,你說我怎么就攤上這事员魏。” “怎么了叠聋?”我有些...
    開封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵撕阎,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我碌补,道長(zhǎng)虏束,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任厦章,我火速辦了婚禮镇匀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘袜啃。我一直安慰自己汗侵,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開白布囊骤。 她就那樣靜靜地躺著晃择,像睡著了一般。 火紅的嫁衣襯著肌膚如雪也物。 梳的紋絲不亂的頭發(fā)上宫屠,一...
    開封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音滑蚯,去河邊找鬼浪蹂。 笑死抵栈,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的坤次。 我是一名探鬼主播古劲,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼缰猴!你這毒婦竟也來了产艾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤滑绒,失蹤者是張志新(化名)和其女友劉穎闷堡,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疑故,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡杠览,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纵势。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片踱阿。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖钦铁,靈堂內(nèi)的尸體忽然破棺而出软舌,到底是詐尸還是另有隱情,我是刑警寧澤牛曹,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布葫隙,位于F島的核電站,受9級(jí)特大地震影響躏仇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜腺办,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一焰手、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧怀喉,春花似錦书妻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至聊闯,卻和暖如春工猜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背菱蔬。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工篷帅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留史侣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓魏身,卻偏偏與公主長(zhǎng)得像惊橱,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子箭昵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容