android圖片壓縮

非原創(chuàng)准谚,只是整理挫剑,如果里面發(fā)現引用的內容沒有標識出來,歡迎指出柱衔。

一樊破、基本知識

(1)兩種圖片:

1)矢量圖:

矢量圖又叫向量圖,是用一系列計算機指令來描述和記錄一幅圖秀存,一幅圖可以解為一系列由點捶码、線、面等到組成的子圖或链,它所記錄的是對象的幾何形狀惫恼、線條粗細和色彩等。生成的矢量圖文件存儲量很小澳盐,無論放大和縮小多少倍祈纯,圖形都有一樣的平滑邊緣和清晰的視覺效果。

例如叼耙,輸入法的文字就是矢量圖腕窥。

2)點陣圖(位圖):

就是圖象由無數個點(像素)組成。每個像素里都由一個顏色表現筛婉,所以點陣圖是有一個個有顏色的點(像素)排列而成簇爆。我們平時看到的文件格式有PSD癞松、TIF、JPG入蛆、GIF等都是點陣圖响蓉,數碼相機拍攝的照片就是點陣圖。

(2)像素(pixel簡稱px):

在位圖中哨毁,圖片是由很多點組成枫甲,那每個點就是1個像素。像素是屏幕中可以顯示的最小元素單元扼褪,我們應用里任何可見的東西都是由一個個像素點組成的想幻。單獨一個像素點非常的微小,肉眼是無法看見的话浇,可是當許許多多的像素點聚集到一起時脏毯,就可以拼接成五彩繽紛的圖案。

(3)屏幕尺寸

屏幕尺寸指屏幕的對角線的長度凳枝,單位是英寸抄沮,1英寸=2.54厘米

比如常見的屏幕尺寸有2.4跋核、2.8岖瑰、3.5、3.7砂代、4.2蹋订、5.0、5.5刻伊、6.0等

(4)分辨率:

圖像分辨率:圖像分辨率是指每英寸圖像內的像素點數露戒。這里的分辨率其實是密度,是指1英寸里有多少像素捶箱。它以 ?像素/英尺(ppi)為單位智什,如一個圖像的分辨率為72ppi,就表示該圖像中每英尺包含72個像素丁屎。(但是現在通常將分辨率表示成每一個方向上的像素數量荠锭,比如 640X480 等。)

屏幕分辨率:屏幕分辨率是指在橫縱向上的像素點數晨川,單位是px证九,1px=1個像素點,每個屏幕有自己的分辨率共虑。一般以縱向像素*橫向像素愧怜,如1960*1080。屏幕分辨率越高妈拌,所呈現的色彩越多拥坛,清晰度越高。

(5)色彩模式

圖像的大小和質量不僅僅由像素總數決定,還跟色彩模型有關猜惋。色彩模型有RGB模式疾党,CMYK模式,位圖模式惨奕,灰度模式等等雪位。

(6)圖片大小

通過一個例子來理解:

選擇一個24位深度分辨率為225×225的位圖,

由于24位位圖是真彩色梨撞,沒有顏色表雹洗,所以

其文件大小為:152154=14+40+(225×3+1)×225

注:因為1個像素用三個字節(jié)來表示,所以乘以3卧波;因為位圖存儲時时肿,Windows規(guī)定一個掃描行所占的字節(jié)數必須是4的倍數(即以long為單位),不足的以0填充,225×3+1剛好是4的倍數港粱;14和40是位圖文件頭和位圖信息頭的字節(jié)大畜Τ伞;

當利用繪圖程序將文件保存為256色查坪,即8位深度的位圖后寸宏,文件大小變?yōu)?2378字節(jié):

52378 = 14 + 50 + 256 × 4 + (225 + 3)× 225

注:256色位圖有顏色表,每個顏色表結構體是4字節(jié)偿曙,所以顏色表這一項占256*4 個字節(jié)氮凝;225+3 剛好湊成4的倍數

可見分辨率沒變,因為位深從24變成了8望忆。所以圖像質量下降了罩阵,圖像大小也變小了。

二启摄、圖片的存在形式:

1.文件形式(即以二進制形式存在于硬盤上)

獲取大小(Byte):File.length()

2.流的形式(即以二進制形式存在于內存中)

獲取大小(Byte):new FileInputStream(File).available()

3.Bitmap形式

獲取大小(Byte):Bitmap.getByteCount()

這三種形式的區(qū)別:

文件形式和流的形式對圖片體積大小并沒有影響,也就是說,如果你手機SD卡上的如果是100K,那么通過流的形式讀到內存中,也一定是占100K的內存,注意是流的形式,不是Bitmap的形式稿壁。當圖片以Bitmap的形式存在時,其占用的內存會變大。

三歉备、bitmap介紹:

(1) Bitmap.Config

一張圖片Bitmap所占用的內存 =圖片長度 x 圖片寬度 x 一個像素點占用的字節(jié)數

而Bitmap.Config傅是,正是指定單位像素占用的字節(jié)數的重要參數。

其中威创,A代表透明度落午;R代表紅色;G代表綠色肚豺;B代表藍色溃斋。

ALPHA_8

表示8位Alpha位圖,即A=8,一個像素點占用1個字節(jié),它沒有顏色,只有透明度

ARGB_4444

表示16位ARGB位圖,即A=4,R=4,G=4,B=4,一個像素點占4+4+4+4=16位吸申,2個字節(jié)

ARGB_8888

表示32位ARGB位圖梗劫,即A=8,R=8,G=8,B=8,一個像素點占8+8+8+8=32位享甸,4個字節(jié)

RGB_565

表示16位RGB位圖,即R=5,G=6,B=5,它沒有透明度,一個像素點占5+6+5=16位,2個字節(jié)

Bitmap.Config主要作用是:

以何種方式像素存儲梳侨。不同的配置將會影響圖像的畫質(色彩深度)蛉威,位數越高畫質越高,顯然在這里ARGB_8888是最占內存的走哺。當然蚯嫌,畫質越高也就越占內存了。

Tips:由于ARGB_4444的畫質慘不忍睹丙躏,一般假如對圖片沒有透明度要求的話择示,可以改成RGB_565,相比ARGB_8888將節(jié)省一半的內存開銷晒旅。


配置不同Bitmap.Config在相同分辨率下的占用內存情況:

一張圖片Bitmap所占用的內存 = 圖片長度 x 圖片寬度 x 一個像素點占用的字節(jié)數

在Android里面可以通過下面的代碼來設置解碼率

(2) Bitmap.CompressFormat

從字面上理解栅盲,它的含義是:Bitmap壓縮格式

其實這個參數很簡單,就是指定Bitmap是以JPEG废恋、PNG還是WEBP格式來壓縮

(3) Bitmap.compress()方法

重磅方法來了谈秫,通過這個方法,可以實現圖片的壓縮鱼鼓。使用該方法需要傳三個參數進去:

CompressFormat

指定Bitmap的壓縮格式拟烫,可選擇JPEG、PNG蚓哩、WEBP

int類型的quality

指定Bitmap的壓縮品質构灸,范圍是0 ~ 100;該值越高岸梨,畫質越高。0表示畫質最差稠氮,100畫質最高曹阔。

OutputStream

指定Bitmap的字節(jié)輸出流。一般使用:

ByteArrayOutputStream stream = new ByteArrayOutputStream();

這個方法不改變圖片分辨率隔披,只通過改變編碼格式來改變每個像素大小赃份,從而改變圖片大小和質量。

四奢米、BitmapFactory

BitmapFactory是獲取Bitmap和壓縮Bitmap的重要類抓韩,下面開始介紹BitmapFactory幾個重要的成員變量和方法:

(1)通過BitmapFactory解碼(獲取)Bitmap的幾種方式

1)decodeFile()//從SD卡文件讀取

Bitmap ?bm=BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath()+"/photo.jpg");

2)decodeResource()//從資源文件res讀取

Bitmap bm=BitmapFactory.decodeResource(this.getResources(), R.mipmap.test_pic);

3)decodeStream()//從輸入流讀取

Bitmap bm=BitmapFactory.decodeStream(inputStream);

4)decodeByteArray()//從字節(jié)數組讀取

Bitmap bm=BitmapFactory.decodeByteArray(bytes,0,bytes.length);


(2)BitmapFactory.Options

BitmapFactory在使用方法decodeFile()、decodeResource()解碼圖片時鬓长,可以指定它的BitmapFactory.Options谒拴。

這個參數作用非常大,它可以設置Bitmap的采樣率涉波,通過改變圖片的寬度英上、高度炭序、縮放比例等,以達到降低圖片的像素的目的苍日,這樣可以做到圖片壓縮惭聂,減少Bitmap的內存

下面列出BitmapFactory.Options的部分成員變量:


in開頭的代表的就是設置某參數;out開頭的代表的就是獲取某參數相恃。比如辜纲,inSampleSize就是設置Bitmap的縮放比例、outWidth就是獲取Bitmap的高度拦耐。

1)?inJustDecodeBounds 設置只去讀圖片的附加信息(寬高),不去解析真實的Bitmap

從字面上理解侨歉,它的含義是:”設置僅解碼Bitmap的邊界”。那它真正的作用是啥呢揩魂?

當inJustDecodeBounds設置為true的時候幽邓,BitmapFactory通過decodeResource或者decodeFile解碼圖片時,將會返回空(null)的Bitmap對象火脉,這樣可以避免Bitmap的內存分配牵舵,但是它可以返回Bitmap的寬度、高度以及MimeType倦挂。


這樣做的意義就在于畸颅,可以先不用產生Bitmap內存,從而獲得圖片的寬高信息方援,盡可能的做到節(jié)約內存耸棒。

2)inSampleSize 設置圖片的縮放比例(寬和高)

這里注意醋闭,google推薦用2的倍數:

在這里著重講一下這個inSampleSize。從字面上理解,它的含義是:”設置取樣大小“悴晰。

它的作用是:設置inSampleSize的值(int類型)后,假如設為4捎拯,則寬和高都為原來的1/4你弦,寬高都減少了,自然內存也降低了呀非。

如圖所示:

在這里參考Google官方文檔來解釋:

http://developer.android.com/intl/zh-cn/training/displaying-bitmaps/load-bitmap.html#load-bitmap

如何理解”設置取樣大小“呢坚俗?如果你認真看了上面的內容話,聰明的你一定知道岸裙,肯定需要配合inJustDecodeBounds猖败,先獲取圖片的寬、高【這個過程就是取樣】降允,然后通過獲取的寬高恩闻,動態(tài)的設置inSampleSize的值。

【當然拟糕,你也可以不動態(tài)判呕,可以寫死inSampleSize的值倦踢。比如設置inSampleSize = 4的話,一張分辨率為2048x1536px的圖像將使用inSampleSize值為4的設置來解碼侠草,產生的Bitmap大小約為512*384px辱挥。相較于完整圖片占用12M的內存,這種方式只需0.75M內存(假設Bitmap配置為ARGB_8888)边涕∥畹猓】

四、兩種壓縮方式:

(1)質量壓縮:

將圖片保存到本地時進行壓縮, 即將圖片從Bitmap形式變?yōu)镕ile形式時進行壓縮

該方法是利用compress方法功蜓。壓縮圖片的質量, 它不會減少圖片的像素园爷。

比方說, 你的圖片是300K的, 1280*700像素的, 經過該方法壓縮后, File形式的圖片是在100k以下, 但是你BitmapFactory.decodeFile到內存中,變成Bitmap時,它的像素仍然是1280*700。計算圖片像素的方法是?bitmap.getWidth()和bitmap.getHeight()式撼。

(2)取樣壓縮

通過調整inSampleSize的值童社,在圖片從本地讀到內存時,進行壓縮 ,即圖片從File形式變?yōu)锽itmap形式。這種方式通過改變圖像的尺寸(像素總數)來壓縮著隆,每個像素所占用的大小不變扰楼。

(3)常用的圖片壓縮方法是將兩者結合。


參考資料:

http://blog.sina.com.cn/s/blog_9e1e8c1301015xat.html

http://www.tuicool.com/articles/eue6z2

http://anany.me/2015/10/15/bitmap1/

https://developer.android.com/training/displaying-bitmaps/load-bitmap.html

http://www.bubuko.com/infodetail-1041128.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末美浦,一起剝皮案震驚了整個濱河市弦赖,隨后出現的幾起案子,更是在濱河造成了極大的恐慌浦辨,老刑警劉巖蹬竖,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異流酬,居然都是意外死亡币厕,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門康吵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來劈榨,“玉大人,你說我怎么就攤上這事晦嵌。” “怎么了拷姿?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵惭载,是天一觀的道長。 經常有香客問我响巢,道長描滔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任踪古,我火速辦了婚禮含长,結果婚禮上券腔,老公的妹妹穿的比我還像新娘。我一直安慰自己拘泞,他們只是感情好纷纫,可當我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著陪腌,像睡著了一般辱魁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诗鸭,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天染簇,我揣著相機與錄音,去河邊找鬼强岸。 笑死锻弓,一個胖子當著我的面吹牛,可吹牛的內容都是我干的蝌箍。 我是一名探鬼主播青灼,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼十绑!你這毒婦竟也來了聚至?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤本橙,失蹤者是張志新(化名)和其女友劉穎扳躬,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體甚亭,經...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡贷币,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了亏狰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片役纹。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖暇唾,靈堂內的尸體忽然破棺而出促脉,到底是詐尸還是另有隱情,我是刑警寧澤策州,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布瘸味,位于F島的核電站,受9級特大地震影響够挂,放射性物質發(fā)生泄漏旁仿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一孽糖、第九天 我趴在偏房一處隱蔽的房頂上張望枯冈。 院中可真熱鬧毅贮,春花似錦、人聲如沸尘奏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽罪既。三九已至铸题,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間琢感,已是汗流浹背丢间。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留驹针,地道東北人烘挫。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像柬甥,于是被迫代替她去往敵國和親饮六。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內容