整理:android開發中對圖片的處理方式彙總

LruCache(Least Recently Used Cache) 全稱最近最少使用算法,其主要思想是使用SoftReference(或者WeakReference),因爲我們的緩存容量是有限的,它會面臨一個問題:當有新的內容需要加入我們的緩存,但我們的緩存空閒的空間不足以放進新的內容時,我們就需要捨棄原有的部分內容從而騰出空間用來放新的內容。

在LruCache 中,我們使用url做key,bitmap做value,利用軟引用的特性(在內存將滿的時候會被垃圾回收器回收,如果還有可用內存,垃圾回收器不會)及時的回收內存,這種方式能夠及時有效回收圖片所佔用的內存,但這些方法並未完全解決單個圖片佔用內存過大的問題,在程序運行的過程中,圖片該多大還多大。我們只是控制在內存中存在圖片對象的個數而已。

與Lru相似的還有Lfu,前者是最近最少使用,即淘汰最長時間未使用的對象;後者是最近最不常使用,即淘汰一段時間內使用最少的對象。比如我們緩存對象的順序是:A B C B D A C A ,當需要淘汰一個對象時,如果採用LRU算法,則淘汰的是B,因爲它是最長時間未被使用的。如果採用LFU算法,則淘汰的是D,因爲在這段時間內它只被使用了一次,是最不經常使用的。

注意:對於SoftReference(軟引用)或者WeakReference(弱引用)的Bitmap緩存方案,現在已經不推薦使用了。自Android2.3版本(API Level 9)開始,垃圾回收器更着重於對軟/弱引用的回收。

與此種方法類似,我們可以使用硬盤緩存(DiskLruCache)來進行圖片的管理,這種方法比LruCache 節省內存,但讀取速度較慢(硬盤的讀取速度是未知的)。

2. 按照一定規則壓縮圖片(以android爲例)

Android中圖片是以bitmap形式存在的,那麼bitmap所佔內存,直接影響到了應用所佔內存大小。

bitmap所佔內存大小計算方式:

圖片長度 x 圖片寬度 x 一個像素點佔用的字節數

以下是圖片的壓縮格式:

![BitMap 格式類型](https://img-blog.csdn.net/20161215104040200?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXE1NjQwNDU4Njc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

其中,A代表透明度;R代表紅色;G代表綠色;B代表藍色。

ALPHA_8

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

ARGB_4444

表示16位ARGB位圖,即A=4,R=4,G=4,B=4,一個像素點佔4+4+4+4=16位,2個字節

ARGB_8888

表示32位ARGB位圖,即A=8,R=8,G=8,B=8,一個像素點佔8+8+8+8=32位,4個字節

RGB_565

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

2.1 質量壓縮(android sdk 提供)

ByteArrayOutputStream baos =newByteArrayOutputStream();//內存流bitmapOld.compress(CompressFormat.JPEG, quality, baos);//quality爲壓縮百分比//quality=50,意爲壓縮爲1/2byte[] bytes = baos.toByteArray();bitmapNew= BitmapFactory.decodeByteArray(bytes,0, bytes.length);//生成圖片對象

通過此種方式,圖片的大小是沒有變的,因爲質量壓縮不會減少圖片的像素,它是在保持像素的前提下改變圖片的位深及透明度等,來達到壓縮圖片的目的,這也是爲什麼該方法叫質量壓縮方法。圖片的長,寬,像素都不變,那麼bitmap所佔內存大小是不會變的。

但是bytes.length是隨着quality變小而變小的。這樣適合去傳遞二進制的圖片數據,比如微信分享圖片,要傳入二進制數據過去,限制32kb之內。

如果是bit.compress(CompressFormat.PNG, quality, baos);這樣的png格式,quality就沒有作用了,bytes.length也不會變化,因爲png圖片是無損的,不能進行壓縮。

2.2 採樣率壓縮(android sdk 提供)

BitmapFactory.Optionsoptions = new BitmapFactory.Options();options.inSampleSize=2;    //inSampleSize 爲壓縮比        此處爲1/2bm = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath()+"/DCIM/Camera/test.jpg", options);

設置inSampleSize的值(int類型)後,假如設爲2,則寬和高都爲原來的1/2,寬高都減少了,圖片總像素就減少了,自然內存也降低了。

Glide默認加載圖片時是通過將圖片轉換成ImageView的大小後再加載。

Picasso默認是加載了全尺寸的圖片到內存,然後讓GPU來實時重繪大小(也可以手動設置或者將scaletype設置成  centerCrop等)。

2.3 縮放法壓縮(martix,android sdk 提供)

Matrix matrix = new Matrix();matrix.setScale(0.5f,0.5f);bm = Bitmap.createBitmap(bit,0,0, bit.getWidth(),bit.getHeight(), matrix, true);

通過上述代碼,bitmap的長度和寬度分別縮小了一半,圖片大小縮小了四分之一。

2.4 RGB_565法

BitmapFactory.Optionsoptions = new BitmapFactory.Options();options.inPreferredConfig= Bitmap.Config.RGB_565;  //將格式設置成RGB_565bm = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath()                    +"/DCIM/Camera/test.jpg", options);

經過此種方式,圖片大小直接縮小了一半,長度和寬度也沒有變,相比argb_8888減少了一半的內存。

注意:由於ARGB_4444的畫質慘不忍睹,一般假如對圖片沒有透明度要求的話,可以改成RGB_565,相比ARGB_8888將節省一半的內存開銷。

Glide默認的Bitmap格式就是RGB_565

Picasso是ARGB_8888

2.5 createScaledBitmap

bitmapNew=Bitmap.createScaledBitmap(bitmapOld,150,150,true);

這裏是將圖片壓縮成我們所期望的長度和寬度(150,150)。 

圖片的內存大小相應也發生了改變。

但是這裏要說,如果用戶期望的長度和寬度和原圖長度寬度相差太多的話,圖片會很不清晰。

android 中 Bitmap壓縮都是圍繞這個來做文章:Bitmap所佔用的內存 = 圖片長度 x 圖片寬度 x 一個像素點佔用的字節數。3個參數,任意減少一個的值,就達到了壓縮的效果。

2.6 Bitmap.recycle() 用於不再使用的圖片對象的處理

該方法不是真正降低圖片內存的方法。主要目的是標記圖片對象,方便回收圖片對象的本地數據。

圖片對象的本地數據佔用的內存最大,而且與程序Java部分的內存是分開計算的。所以經常出現Java heap足夠使用,而圖片發生OutOfMemoryError的情況。在圖片不使用時調用該方法,可以有效降低圖片本地數據的峯值,從而減少OutOfMemoryError的概率。不過調用了recycle()的圖片對象處於“廢棄”狀態,調用時會造成程序錯誤。所以在無法保證該圖片對象絕對不會被再次調用的情況下,不建議使用該方法。

特別要注意已經用setImageBitmap(Bitmap img)方法分配給控件的圖片對象(意爲img存在其他地方的引用),可能會被系統類庫調用,造成程序錯誤。

3.處理美工給的UI圖 tinypng(網站)

一個很好的批處理壓縮圖片文件的網站(工具),可將圖片壓縮至70%左右。 

網站鏈接:https://tinypng.com

但這種方式只能處理美工給的切圖,不能處理來自服務器的圖片文件。

4.webP圖片格式(android,ios均適用)

WebP圖片格式,由谷歌於2010年推出的新一代圖片格式,在壓縮方面比當前JPEG格式更優越。圖片壓縮體積大約只有JPEG的2/3,並能節省大量的服務器帶寬資源和數據空間。Facebook Ebay等知名網站已經開始測試並使用WebP格式。

但WebP是一種有損壓縮。相較編碼JPEG文件,編碼同樣質量的WebP文件需要佔用更多的計算資源。

谷歌表示,這種格式的主要優勢在於高效率。他們發現,“在質量相同的情況下,WebP格式圖像的體積要比JPEG格式圖像小40%。谷歌瀏覽器已經支持webp格式,Opera在版本號Opera11.10後也增加了支持,然而火狐和ie暫時還不支持webp格式,可以採用flash插件來顯示webp,當然這樣會耗費一些性能。

美中不足的是,WebP格式圖像的編碼時間“比JPEG格式圖像長8倍”(佔用cpu,節省內存)。

分析人士認爲,儘管WebP格式尚未像JPEG格式那樣,得到各種軟硬件的廣泛支持,但谷歌推廣這一格式的優勢在於Chrome瀏覽器。這款谷歌開發的瀏覽器的市場份額已達10%以上。

桌面版Chrome可打開WebP格式。

常用的webp轉換工具有:XnConvet,智圖,ISparta,集成方法請自行百度。

http://www.bkjia.com/Androidjc/1019610.html

5 .圖片上傳 (推薦使用luban from github)

一款仿微信的圖片壓縮庫,一般用作上傳圖片的壓縮 

 感謝:http://blog.csdn.net/qq564045867/article/details/53666893

相關:http://www.jianshu.com/p/1759364ca8b6

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章