關(guān)于android 圖片壓縮你需要知道的事

關(guān)鍵詞: Bitmap,質(zhì)量壓縮,比例壓縮,采樣率壓縮,微信分享

前言


android 系統(tǒng)的圖片壓縮大體上有三種方式词爬,質(zhì)量壓縮矿酵,比例壓縮给涕,采樣率壓縮

一般最簡單直觀的應(yīng)該是bitmap.compress方法著拭,把位圖的壓縮信息寫入到一個(gè)指定的輸出流帅容,其中有一個(gè)參數(shù)quality,取值0-100银伟,數(shù)值越小你虹,輸出流越小。但是無論是質(zhì)量壓縮彤避,比例壓縮傅物,還是采樣率壓縮,單獨(dú)使用可能都沒法達(dá)到理想的效果琉预。比如微信的32k限制董饰,單純的質(zhì)量壓縮就無法達(dá)到要求。所以我不得不花些時(shí)間分析這三種壓縮方式圆米,最后把這三種方式結(jié)合在一起卒暂,才得出了一個(gè)比較理想的壓縮結(jié)果,以下是對(duì)這幾種壓縮方式的一個(gè)整理娄帖。

質(zhì)量壓縮


1.代碼:

    public static Bitmap getCompressBitmapByQuality(Bitmap bitmap, int quality) {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
            ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
            return BitmapFactory.decodeStream(inputStream, null, null);
    }

2.關(guān)于質(zhì)量壓縮

關(guān)于質(zhì)量壓縮需要注意的是質(zhì)量壓縮只改變了圖片的位深及透明度也祠,但是并沒有改變Bitmap在內(nèi)存中的大小
即上邊的代碼只改變了ByteArrayOutputStream 的大小,如果把壓縮過的Bitmap保存到文件中块茁,文件的大小會(huì)變小齿坷,但是Bitmap本身的大小不會(huì)變

這里有一個(gè)延伸的知識(shí)點(diǎn):Bitmap在內(nèi)存中的占用大小是由什么決定的呢?
google對(duì)于bitmap大小的獲取在不同的API版本中有不同的方法
Api 19: 以上用getAllocationByteCount()
Api 12: 以上用getByteCount()
更早: 自己算:-)

我們可以先看看這個(gè)函數(shù) Bitmap.getByteCount()

    /**
     * Returns the minimum number of bytes that can be used to store this bitmap's pixels.
     *
     * <p>As of {@link android.os.Build.VERSION_CODES#KITKAT}, the result of this method can
     * no longer be used to determine memory usage of a bitmap. See {@link
     * #getAllocationByteCount()}.</p>
     */
    public final int getByteCount() {
        // int result permits bitmaps up to 46,340 x 46,340
        return getRowBytes() * getHeight();
    }

其中getRowBytes() 是bitmap 中每一行所占的比特?cái)?shù)桂肌,乘以bitmap的高度getHeight(),就是bitmap在內(nèi)存中所占用的空間大小,其中g(shù)etRowBytes()和bitmap的寬度還有bitmap所使用的色彩格式有關(guān)系永淌,比如如果使用的是ARGB_8888 那么getRowBytes()的大小就是bitmap.getWidth()4,乘以4*的原因是在ARGB_8888的色彩格式中崎场,每個(gè)像素點(diǎn)占4位。
android系統(tǒng)中的色彩模式有一下幾種

Bitmap.Config 描述 占用內(nèi)存(字節(jié))
Bitmap.Config ARGB_8888 表示32位的ARGB位圖 4
Bitmap.Config ARGB_4444 表示16位的ARGB位圖 2
Bitmap.Config RGB_565 表示16位的RGB位圖 2
Bitmap.Config ALPHA_8 表示8位的Alpha位圖 1

由此可見bitmap在內(nèi)存中的大小相關(guān)的因素是:像素點(diǎn),分辨率(寬x高),色彩模式

比例壓縮


1.代碼

public static Bitmap getCompressBitmapByScale(Bitmap bitmap, int maxW, int maxH) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();

        float sx = (float) maxW / (float) w;
        float sy = (float) maxH / (float) h;

        Matrix matrix = new Matrix();
        matrix.setScale(sx, sy);
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}

2.關(guān)于比例壓縮

比例壓縮通過改變bitmap的寬高遂蛀,可以顯著改變圖片大小谭跨,但是如果縮放過度了,圖片也會(huì)完全糊掉李滴。一般會(huì)按照一個(gè)指定的比例(比如 scale=0.8)循環(huán)縮放,直到壓到合適的尺寸

采樣率壓縮


1.代碼

public static Bitmap getCompressBitmapBySampleSize(Bitmap bitmap, int sampleSize) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = sampleSize;

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
        return BitmapFactory.decodeByteArray(outputStream.toByteArray(), 0, outputStream.toByteArray().length, options);
}

2.關(guān)于采樣率

采樣率為1的時(shí)候?yàn)樵即笮◇χ妫瑸?的時(shí)候,寬高為原來的1/2所坯,像素?cái)?shù)和占用內(nèi)存數(shù)為原來1/4,采樣率是2的指數(shù)谆扎。

谷歌提供的一個(gè)關(guān)于采樣率的計(jì)算方法:

public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) >= reqHeight
                && (halfWidth / inSampleSize) >= reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

分享到微信的壓縮算法


最后提供一個(gè)分享到微信的壓縮算法,基本上是結(jié)合了采樣率壓縮芹助,比例壓縮和質(zhì)量壓縮,在把圖片壓縮到指定大小的同時(shí)堂湖,盡可能保證圖片的清晰度

這是一個(gè)圖片壓縮的demo,三種壓縮方式都有一個(gè)簡單的實(shí)現(xiàn)
https://github.com/jhwing/ImageCompress
這是一個(gè)社會(huì)化分享的sdk状土,支持微信无蜂,微博,qq蒙谓,三個(gè)平臺(tái)的分享功能,關(guān)于圖片壓縮的算法在這個(gè)sdk里
https://github.com/jhwing/SKShare

延伸閱讀


http://www.cnblogs.com/hrlnw/p/4403334.html
http://blog.csdn.net/lsyz0021/article/details/51356670
https://github.com/bither/bither-android-lib/blob/master/REASON.md
http://blog.csdn.net/angel1hao/article/details/51890938
https://github.com/zetbaitsu/Compressor
https://developer.android.com/training/displaying-bitmaps/load-bitmap.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末斥季,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子累驮,更是在濱河造成了極大的恐慌酣倾,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件慰照,死亡現(xiàn)場離奇詭異灶挟,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)毒租,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來箱叁,“玉大人墅垮,你說我怎么就攤上這事「” “怎么了算色?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長螟够。 經(jīng)常有香客問我灾梦,道長峡钓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任若河,我火速辦了婚禮能岩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘萧福。我一直安慰自己拉鹃,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布鲫忍。 她就那樣靜靜地躺著膏燕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪悟民。 梳的紋絲不亂的頭發(fā)上坝辫,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音射亏,去河邊找鬼阀溶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛鸦泳,可吹牛的內(nèi)容都是我干的银锻。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼做鹰,長吁一口氣:“原來是場噩夢啊……” “哼击纬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起钾麸,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤更振,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后饭尝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肯腕,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年钥平,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了实撒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涉瘾,死狀恐怖知态,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情立叛,我是刑警寧澤负敏,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站秘蛇,受9級(jí)特大地震影響其做,放射性物質(zhì)發(fā)生泄漏顶考。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一妖泄、第九天 我趴在偏房一處隱蔽的房頂上張望驹沿。 院中可真熱鬧,春花似錦浮庐、人聲如沸甚负。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梭域。三九已至,卻和暖如春搅轿,著一層夾襖步出監(jiān)牢的瞬間病涨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來泰國打工璧坟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留既穆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓雀鹃,卻偏偏與公主長得像幻工,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子黎茎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,138評(píng)論 25 707
  • LZ-Says:小沈陽版程序員~~~程序員其實(shí)可痛苦的了......需求一做一改囊颅,一個(gè)月就過去了;嚎~需求再一改一...
    靜心Study閱讀 3,840評(píng)論 1 14
  • 之前有個(gè)萌新在技術(shù)群里問圖片壓縮傅瞻,然后我竟然還要查資料才回答他踢代,沒辦法,誰讓我也是個(gè)萌新嗅骄,所以打算寫一篇文章來復(fù)習(xí)...
    鍵盤上的麒麟臂閱讀 5,618評(píng)論 11 18
  • 一線天二紫臺(tái)三星烽火映斜陽 四方城五孤刃六道輪回恥難忘 七雄魂八仙魄九州大陸龍圖揚(yáng) 十年百載千秋萬代枯骨葬邊疆 茫...
    逝時(shí)何奈_傾酒作愁閱讀 208評(píng)論 3 0
  • 故事發(fā)生在二戰(zhàn)時(shí)期的法國:紅白相間的教會(huì)醫(yī)院胳挎,草坪和午后陽光,十足老電影里的情調(diào)溺森。兩個(gè)被喚作天使的護(hù)士慕爬,一個(gè)是主人...
    簡微檸Jean閱讀 192評(píng)論 0 2