Android中圖片是以bitmap形式存在的,那么bitmap所占內(nèi)存,直接影響到了應(yīng)用所占內(nèi)存大小,首先要知道bitmap所占內(nèi)存大小計算方式:
喀什網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站等網(wǎng)站項目制作,到程序開發(fā),運營維護(hù)。成都創(chuàng)新互聯(lián)公司于2013年創(chuàng)立到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)公司。
圖片長度 x 圖片寬度 x 一個像素點占用的字節(jié)數(shù)
以下是圖片的壓縮格式:
其中,A代表透明度;R代表紅色;G代表綠色;B代表藍(lán)色。
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é)
我是用的小米手機(jī)2s來測試的,從sd卡取出一個照片,如下所示:
bit = BitmapFactory.decodeFile(Environment .getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera/test.jpg"); Log.i("wechat", "壓縮前圖片的大小" + (bit.getByteCount() / 1024 / 1024) + "M寬度為" + bit.getWidth() + "高度為" + bit.getHeight());
出來的log是:
將取得的bitmap進(jìn)行壓縮,下面開始說,bitmap的幾種壓縮方式。
1.質(zhì)量壓縮
ByteArrayOutputStream baos = new ByteArrayOutputStream(); int quality = Integer.valueOf(editText.getText().toString()); bit.compress(CompressFormat.JPEG, quality, baos); byte[] bytes = baos.toByteArray(); bm = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); Log.i("wechat", "壓縮后圖片的大小" + (bm.getByteCount() / 1024 / 1024) + "M寬度為" + bm.getWidth() + "高度為" + bm.getHeight() + "bytes.length= " + (bytes.length / 1024) + "KB" + "quality=" + quality);
其中quality是從edittext獲取的數(shù)字,可以從0–100改變,這里出來的log是:
可以看到,圖片的大小是沒有變的,因為質(zhì)量壓縮不會減少圖片的像素,它是在保持像素的前提下改變圖片的位深及透明度等,來達(dá)到壓縮圖片的目的,這也是為什么該方法叫質(zhì)量壓縮方法。那么,圖片的長,寬,像素都不變,那么bitmap所占內(nèi)存大小是不會變的。
但是我們看到bytes.length是隨著quality變小而變小的。這樣適合去傳遞二進(jìn)制的圖片數(shù)據(jù),比如微信分享圖片,要傳入二進(jìn)制數(shù)據(jù)過去,限制32kb之內(nèi)。
這里要說,如果是bit.compress(CompressFormat.PNG, quality, baos);這樣的png格式,quality就沒有作用了,bytes.length不會變化,因為png圖片是無損的,不能進(jìn)行壓縮。
CompressFormat還有一個屬性是,CompressFormat.WEBP格式,該格式是google自己推出來一個圖片格式,更多信息,文末會貼出地址。
2.采樣率壓縮
BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; bm = BitmapFactory.decodeFile(Environment .getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera/test.jpg", options); Log.i("wechat", "壓縮后圖片的大小" + (bm.getByteCount() / 1024 / 1024) + "M寬度為" + bm.getWidth() + "高度為" + bm.getHeight());
出來的log是
設(shè)置inSampleSize的值(int類型)后,假如設(shè)為2,則寬和高都為原來的1/2,寬高都減少了,自然內(nèi)存也降低了。
我上面的代碼沒用過options.inJustDecodeBounds = true; 因為我是固定來取樣的數(shù)據(jù),為什么這個壓縮方法叫采樣率壓縮,是因為配合inJustDecodeBounds,先獲取圖片的寬、高【這個過程就是取樣】,然后通過獲取的寬高,動態(tài)的設(shè)置inSampleSize的值。
當(dāng)inJustDecodeBounds設(shè)置為true的時候,BitmapFactory通過decodeResource或者decodeFile解碼圖片時,將會返回空(null)的Bitmap對象,這樣可以避免Bitmap的內(nèi)存分配,但是它可以返回Bitmap的寬度、高度以及MimeType。
3.縮放法壓縮(martix)
Matrix matrix = new Matrix(); matrix.setScale(0.5f, 0.5f); bm = Bitmap.createBitmap(bit, 0, 0, bit.getWidth(), bit.getHeight(), matrix, true); Log.i("wechat", "壓縮后圖片的大小" + (bm.getByteCount() / 1024 / 1024) + "M寬度為" + bm.getWidth() + "高度為" + bm.getHeight());
出來的log是
可以看出來,bitmap的長度和寬度分別縮小了一半,圖片大小縮小了四分之一。
關(guān)于martix更多信息,文末會有一個參考文章。
4.RGB_565法
BitmapFactory.Options options2 = new BitmapFactory.Options(); options2.inPreferredConfig = Bitmap.Config.RGB_565; bm = BitmapFactory.decodeFile(Environment .getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera/test.jpg", options2); Log.i("wechat", "壓縮后圖片的大小" + (bm.getByteCount() / 1024 / 1024) + "M寬度為" + bm.getWidth() + "高度為" + bm.getHeight());
出來的log是:
我們看到圖片大小直接縮小了一半,長度和寬度也沒有變,相比argb_8888減少了一半的內(nèi)存。
注意:由于ARGB_4444的畫質(zhì)慘不忍睹,一般假如對圖片沒有透明度要求的話,可以改成RGB_565,相比ARGB_8888將節(jié)省一半的內(nèi)存開銷。
5.createScaledBitmap
bm = Bitmap.createScaledBitmap(bit, 150, 150, true); Log.i("wechat", "壓縮后圖片的大小" + (bm.getByteCount() / 1024) + "KB寬度為" + bm.getWidth() + "高度為" + bm.getHeight());
出來的log是
這里是將圖片壓縮成用戶所期望的長度和寬度,但是這里要說,如果用戶期望的長度和寬度和原圖長度寬度相差太多的話,圖片會很不清晰。
總結(jié)
以上就是5種圖片壓縮的方法,這里需要強(qiáng)調(diào),他們的壓縮僅僅只是對android中的bitmap來說的。如果將這些壓縮后的bitmap另存為sd中,他們的內(nèi)存大小并不一樣。
android手機(jī)中,圖片的所占的內(nèi)存大小和很多因素相關(guān),計算起來也很麻煩。為了計算出一個圖片的內(nèi)存大小,可以將圖片當(dāng)做一個文件來間接計算,用如下的方法:
File file = new File(Environment.getExternalStorageDirectory() .getAbsolutePath() + "/DCIM/Camera/test.jpg"); Log.i("wechat", "file.length()=" + file.length() / 1024);
或者
FileInputStream fis = null; try { fis = new FileInputStream(file); } catch (FileNotFoundException e) { e.printStackTrace(); } try { Log.i("wechat", "fis.available()=" + fis.available() / 1024); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
上面兩個方法計算的結(jié)果是一樣的。
看完了這篇內(nèi)容,其實說白了,Bitmap壓縮都是圍繞這個來做文章:Bitmap所占用的內(nèi)存 = 圖片長度 x 圖片寬度 x 一個像素點占用的字節(jié)數(shù)。3個參數(shù),任意減少一個的值,就達(dá)到了壓縮的效果。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。