Bitmap知識點

采樣率壓縮

根據(jù)ImageView的大小,通過設置inSampleSize采樣率,加載壓縮后的圖片。如下:

    /**
     * Bitmap采樣率壓縮[推薦壓縮方案]
     *
     * @param resources
     * @param resourcesId 圖片資源ID
     * @param requestWidth 需要適配的寬度
     * @param requestHeight  需要適配的高度
     */
    public static Bitmap decodeBitmapFromResource(Resources resources,
                         int resourcesId, int requestWidth, int requestHeight) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        //1, true 只會解析圖片的原始寬、高,不會真正的加載圖片。
        options.inJustDecodeBounds = true;
        //2, 獲取加載圖片顯示在ImageView上的采樣率(采樣lv會造成一定程度的失真)
        options.inSampleSize = calculateInSampleSize(options, 
                                    requestWidth, requestHeight);
        //3, false 可以獲取圖片的Bitmap                            
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(resources, resourcesId, options);
    }

    private static int calculateInSampleSize(BitmapFactory.Options options,
                       int requestWidth, int requestHeight) {
        if (options == null) return 1;
        //通過options.outWidth獲取的寬高和圖片所放目錄及屏幕密度有關。
        final int originWidth = options.outWidth;
        final int originHeight = options.outHeight;
        int inSampleSize = 1;
        boolean flag = (originWidth > requestWidth * inSampleSize)
                && (originHeight > requestHeight * inSampleSize);
        do {
            inSampleSize *= 2;
        } while (flag);
        return inSampleSize;
    }

inSampleSize的值應為2的非負整數(shù)次冪(1,2,4,... ),否則會被系統(tǒng)向下取整并找到一個最接近的值。

Bitmap

Bitmap.compress(...):負責向輸入流中寫入一個針對透明度、圖像深度的壓縮版本Bitmap,即質(zhì)量壓縮

/**
* 向指定的輸出流中寫入一個壓縮版本的位圖,主要針對透明度、圖像深度等進行壓縮。
* 
* @param format   要壓縮圖片的格式。
* @param quality  表示圖片壓縮質(zhì)量,范圍0-100,0表示將圖片質(zhì)量壓縮成最小,
*                 100表示將圖片質(zhì)量壓縮成最大(個人理解為不壓縮)。
*                 本身是PNG格式的圖片會無視質(zhì)量壓縮,本身是Jpeg格式的圖片壓縮成PNG格式內(nèi)存會變大。
* @param stream   壓縮數(shù)據(jù)將要寫入的輸出流。
* 
* 如果返回true,表示成功壓縮到對應的流中。
*/
@WorkerThread
public boolean compress(CompressFormat format,int quality,OutputStream stream)

質(zhì)量壓縮并不能改變圖片在內(nèi)存中的占用,只是改變輸出流在文件中的大小。一般用于上傳文件時將Btimap壓縮成流,降低上傳流量成本。

Bitmap.getAllocationByteCount()/getByteCount():獲取位圖所占內(nèi)存。

/**
* 獲取此Bitmap所占內(nèi)存。
* 在Android API19后,推薦用getAllocationByteCount(),表示獲得Bitmap已分配過的內(nèi)存(推薦理由:引用未置空,內(nèi)存不回收)。
* 如果該Bitmap 未 被重復用來解碼其他尺寸的Bitmap時,兩方法值相同。
*/
public final int getByteCount() {
  if (mRecycled) {
      return 0;
  }
  //getHeight()是圖片加載的高度(單位:pix)
  return getRowBytes() * getHeight();
}

Bitmap內(nèi)存重用: 在Android API19 之前只能重用相同大小的Bitmap的內(nèi)存,而Android 4.4及以后版本則只要后來的Bitmap比之前的小即可。多個Bitmap可以復用一塊內(nèi)存,減少內(nèi)存開支,提高性能。

BitmapFactory

BitmapFactory類負責創(chuàng)建Bitmap,一般從files、streams或byte數(shù)組中獲取數(shù)據(jù)源。具體調(diào)用方法有decodeFile,decodeResource,decodeStream和decodeByteArray。

/**
 * 配置圖片的色彩模式
 * 如果不為空,解碼器在解析時會按此配置解析。
 * 如果為空或無法滿足請求時,解碼器會根據(jù)屏幕色深選擇最佳配置。
 * 如果原始圖片有透明度的話,也會按此配置設置。
 * 
 * 可配置ALPHA_8,RGB_565,ARGB_4444,ARGB_8888(默認值)
 */
 public Bitmap.Config inPreferredConfig = Bitmap.Config.ARGB_8888;

如果為空或無法滿足請求時,系統(tǒng)會自動選擇最佳色彩模式。

色彩模式:

ARGB分別表示Alpha(透明度)通道,R(red紅色)通道,G(Green綠色)通道,(Blue藍色)通道。

  • ALPHA_8: ALPHA通道占用8位,即1個字節(jié)
  • RGB_565: R通道占用5位,G通道占用6位,B通道占用5位,共16位即2個字節(jié)
  • ARGB_4444: A,R,G,B四個通道各占用4位,共16位即2個字節(jié)
  • ARGB_8888: A,R,G,B四個通道各占用8位,共32位即4個字節(jié)

根據(jù)色彩模式的命名即可知道各個通道所占位或字節(jié)(1Byte = 8bit)。

Bitmap占用內(nèi)存

Bitmap占用內(nèi)存= 圖片最終加載的分辨率 * 被動壓縮比^2 * 單位像素內(nèi)存。

影響B(tài)itmap占用內(nèi)存的因素:

  • 圖片最終加載的分辨率;
  • 圖片的格式(PNG/JPEG/BMP/WebP);
  • 圖片所存放的drawable目錄;
  • 圖片屬性設置的色彩模式;
  • 設備的屏幕密度;

圖片最終加載的分辨率:即圖片經(jīng)過壓縮、裁剪等方式,最終加載到Bitmap中的分辨率。一般通過設置主動壓縮比,或在XML中設置scaleType屬性,或設置ImageView的寬高進行壓縮、裁剪。

主動壓縮比

  • 通過設置inSampleSize縮放值,設置圖片最終要加載的尺寸;
  • Glide的View視圖值/原圖值的縮放比,是讓ImageView的顯示寬高參與主動縮放比計算。

被動壓縮比:設備屏幕密度/圖片所在drawable文件夾屏幕密度

  • 被動縮放比只在當Bitmap文件位于drawable后面有dpi層級的文件中時生效。drawable后面沒有dpi層級文件夾dpi為160;
  • 如果Bitmap位圖文件位于assets包這樣的外部文件或者是URL網(wǎng)絡地址(下載后以File格式存儲在SD卡或緩存),是有沒有被動縮放比的(即默認為1),不影響內(nèi)存結(jié)果。

PNG/JPEG/BMP/WebP格式的區(qū)別:

  1. JPEG格式的圖片不支持Alpha(透明度)屬性的。
  2. PNG是無損壓縮的,無法進行質(zhì)量壓縮。
  3. WebP格式的圖片比JPEG更節(jié)省空間,WebP默認只支持Android 4.0以上。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 在日常開發(fā)中,可以說和Bitmap低頭不見抬頭見,基本上每個應用都會直接或間接的用到,而這里面又涉及到大量的相關知...
    Android高級工程師閱讀 3,291評論 0 4
  • 一、Bitmap 內(nèi)存回收 從3.0開始,Bitmap 像素數(shù)據(jù)和 Bitmap 對象一起存放在 Dalvik 堆...
    秀花123閱讀 1,962評論 1 7
  • 7.1 壓縮圖片 一、基礎知識 1、圖片的格式 jpg:最常見的圖片格式。色彩還原度比較好,可以支持適當壓縮后保持...
    AndroidMaster閱讀 2,702評論 0 13
  • Android Bitmap 知識點梳理 1. 區(qū)別decodeResource()和decodeFile() 這...
    學渣羅小賤閱讀 554評論 0 1
  • 摘要:對android 上圖片壓縮,其實總結(jié)起來基本可以分為兩類壓縮:尺寸壓縮和質(zhì)量壓縮, 尺寸壓縮其實也可以理解...
    男爵是只貓丶閱讀 8,978評論 2 14

友情鏈接更多精彩內(nèi)容