詳解Android Bitmap的常用壓縮方式
一、前言
已經(jīng)好久沒有更新博客,大概有半年了,主要是博主這段時(shí)間忙于找工作,Android崗位的工作真的是越來越難找,好不容易在廣州找到一家,主要做海外產(chǎn)品,公司研發(fā)實(shí)力也不錯(cuò),所以就敲定了三方協(xié)議?,F(xiàn)在已經(jīng)在公司實(shí)習(xí)了一個(gè)月多,目前主要是負(fù)責(zé)公司某個(gè)產(chǎn)品的內(nèi)存優(yōu)化,剛好就總結(jié)了一下Android Bitmap常用的優(yōu)化方式。
Android中的圖片是以Bitmap方式存在的,繪制的時(shí)候也是Bitmap,直接影響到app運(yùn)行時(shí)的內(nèi)存,在Android,Bitmap所占用的內(nèi)存計(jì)算公式是:圖片長度 x 圖片寬度 x像素點(diǎn)的字節(jié)數(shù)
二、圖片常用的壓縮格式
Enum Values | |
---|---|
ALPHA_8 | 每個(gè)像素都存儲(chǔ)為一個(gè)半透明(alpha)通道 |
ARGB_4444 | 此字段已在API級(jí)別13中棄用。由于此配置的質(zhì)量較差,建議使用ARGB_8888 |
ARGB_8888 | 每個(gè)像素存儲(chǔ)在4個(gè)字節(jié)。 |
RGB_565 | 每個(gè)像素存儲(chǔ)在2個(gè)字節(jié)中,只有RGB通道被編碼:紅色以5位精度存儲(chǔ)(32個(gè)可能值),綠色以6位精度存儲(chǔ)(64個(gè)可能值),藍(lán)色存儲(chǔ)為5位精確。 |
其中字母代表的意思我們大概都可以理解,接下來我們來算算它們單個(gè)像素點(diǎn)的字節(jié)數(shù):
- ALPHA_8:表示8位Alpha位圖,即透明度占8個(gè)位,一個(gè)像素點(diǎn)占用1個(gè)字節(jié),它沒有顏色,只有透明度。
- ARGB_4444:表示16位ARGB位圖,即A=4,R=4,G=4,B=4,一個(gè)像素點(diǎn)占4+4+4+4=16位,2個(gè)字節(jié)。
- ARGB_8888:表示32位ARGB位圖,即A=8,R=8,G=8,B=8,一個(gè)像素點(diǎn)占8+8+8+8=32位,4個(gè)字節(jié)。
- RGB_565 :表示16位RGB位圖,即R=5,G=6,B=5,它沒有透明度,一個(gè)像素點(diǎn)占5+6+5=16位,2個(gè)字節(jié)
我們?cè)谧鰤嚎s處理的時(shí)候,可以先通過改變Bitmap的圖片格式,來達(dá)到壓縮的效果,其實(shí)壓縮最主要就是要么改變其寬高,要么就通過減少其單個(gè)像素占用的內(nèi)存。
三、常用的壓縮方法:
1.質(zhì)量壓縮
private void compressQuality() { Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.test); mSrcSize = bm.getByteCount() + "byte"; ByteArrayOutputStream bos = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.JPEG, 100, bos); byte[] bytes = bos.toByteArray(); mSrcBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); }
質(zhì)量壓縮不會(huì)減少圖片的像素,它是在保持像素的前提下改變圖片的位深及透明度,來達(dá)到壓縮圖片的目的,圖片的長,寬,像素都不會(huì)改變,那么bitmap所占內(nèi)存大小是不會(huì)變的。
我們可以看到有個(gè)參數(shù):quality,可以調(diào)節(jié)你壓縮的比例,但是還要注意一點(diǎn)就是,質(zhì)量壓縮堆png格式這種圖片沒有作用,因?yàn)閜ng是無損壓縮。
2.采樣率壓縮
private void compressSampling() { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; mSrcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test, options); }
采樣率壓縮其原理其實(shí)也是縮放bitamp的尺寸,通過調(diào)節(jié)其inSampleSize參數(shù),比如調(diào)節(jié)為2,寬高會(huì)為原來的1/2,內(nèi)存變回原來的1/4.
3.放縮法壓縮
private void compressMatrix() { Matrix matrix = new Matrix(); matrix.setScale(0.5f, 0.5f); Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.test); mSrcBitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); bm = null; }
放縮法壓縮使用的是通過矩陣對(duì)圖片進(jìn)行裁剪,也是通過縮放圖片尺寸,來達(dá)到壓縮圖片的效果,和采樣率的原理一樣。
4.RGB_565壓縮
private void compressRGB565() { BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.RGB_565; mSrcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test, options); }
這是通過壓縮像素占用的內(nèi)存來達(dá)到壓縮的效果,一般不建議使用ARGB_4444,因?yàn)楫嬞|(zhì)實(shí)在是辣雞,如果對(duì)透明度沒有要求,建議可以改成RGB_565,相比ARGB_8888將節(jié)省一半的內(nèi)存開銷。
5.createScaledBitmap
private void compressScaleBitmap() { Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.test); mSrcBitmap = Bitmap.createScaledBitmap(bm, 600, 900, true); bm = null; }
將圖片的大小壓縮成用戶的期望大小,來減少占用內(nèi)存。
四、效果圖
五、總結(jié)
以上5種就是我們常用的壓縮方法了,這里的壓縮也只是針對(duì)在運(yùn)行加載的bitmap占用內(nèi)存的大小。我們?cè)谧鯝pp內(nèi)存優(yōu)化的時(shí)候,一般可以從這兩個(gè)方面入手,一個(gè)內(nèi)存泄漏,另外一個(gè)是Bitmap壓縮了,在要求像素不高的情況下,可以對(duì)Bitmap進(jìn)行壓縮,并且針對(duì)一些只使用一次的bitmap,要做好recycle的處理。
源碼地址:https://github.com/codingma/BitmapCompress
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 詳解Android Bitmap的使用
- android獲取圖片尺寸的兩種方式及bitmap的縮放操作
- Android 實(shí)現(xiàn)把bitmap圖片的某一部分的顏色改成其他顏色
- Android 實(shí)現(xiàn)將Bitmap 保存到本地
- Android中的Bitmap序列化失敗的解決方法
- Android BitmapUtils工具類使用詳解
- Android Bitmap的加載與緩存
- Android中的Bitmap的詳細(xì)介紹
- Android圖片處理工具類BitmapUtils
- Android開發(fā)中Bitmap高效加載使用詳解
- Android中Glide獲取圖片Path、Bitmap用法詳解
- Android Bitmap像素級(jí)操作詳解
相關(guān)文章
Android實(shí)現(xiàn)截圖分享qq 微信功能
在日常生活中,經(jīng)常用到qq,微信截圖分享功能,今天小編通過本文給大家介紹Android實(shí)現(xiàn)截圖分享qq 微信功能,具體實(shí)現(xiàn)代碼大家參考下本文2017-12-12Android實(shí)現(xiàn)點(diǎn)擊AlertDialog上按鈕時(shí)不關(guān)閉對(duì)話框的方法
這篇文章主要介紹了Android實(shí)現(xiàn)點(diǎn)擊AlertDialog上按鈕時(shí)不關(guān)閉對(duì)話框的方法,涉及設(shè)置監(jiān)聽的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02android實(shí)現(xiàn)簡單的活動(dòng)轉(zhuǎn)盤
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)簡單的活動(dòng)轉(zhuǎn)盤,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10Flutter質(zhì)感設(shè)計(jì)之列表項(xiàng)
這篇文章主要為大家詳細(xì)介紹了Flutter質(zhì)感設(shè)計(jì)之列表項(xiàng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08android okhttp的基礎(chǔ)使用【入門推薦】
本文主要總結(jié)了Android著名網(wǎng)絡(luò)框架-okhttp的基礎(chǔ)使用。具有一定的參考價(jià)值,下面跟著小編一起來看下吧2017-01-01Android中捕獲TTextView文本中的鏈接點(diǎn)擊事件方法
這篇文章主要介紹了Android中捕獲TTextView文本中的鏈接點(diǎn)擊事件方法,本文給出了實(shí)現(xiàn)代碼和使用方法以及實(shí)現(xiàn)自己控制的方法,需要的朋友可以參考下2015-01-01android編程實(shí)現(xiàn)sd卡讀取數(shù)據(jù)庫的方法
這篇文章主要介紹了android編程實(shí)現(xiàn)sd卡讀取數(shù)據(jù)庫的方法,涉及Android權(quán)限控制及針對(duì)sd卡與數(shù)據(jù)庫的相關(guān)操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11