首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Android 高效加載大圖片:inSampleSize 縮放與 inJustDecodeBounds 預檢

     編輯:關於C++

問題背景

圖片分辨率往往遠超螢幕顯示需求(如相機拍攝 4000×3000,手機螢幕 1080×1920)。直接載入原圖會佔用大量記憶體,導致 OutOfMemoryError,且影響滑動流暢度。解決方案:載入縮放後的版本,尺寸匹配 UI 控件大小。

核心 API:BitmapFactory.Options

  • inJustDecodeBounds = true:不分配記憶體,僅解碼邊界,獲取 outWidth, outHeight, outMimeType。
  • inSampleSize:縮放比例(2 的冪),如設為 4,寬高各縮小 4 倍,記憶體佔用約 1/16。

計算最佳 inSampleSize

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    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;
        while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
            inSampleSize *= 2;
        }
    }
    return inSampleSize;
}

原理:取最大的 2 的冪,使縮放後寬高仍 ≥ 目標尺寸。解碼器最終會向下取最接近的 2 的冪。

完整加載流程

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
    // 1. 預檢尺寸
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);
    // 2. 計算縮放比
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    // 3. 真正解碼
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

使用示例

mImageView.setImageBitmap(
    decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100)
);

其他數據源

同理可用 decodeFile, decodeByteArray, decodeStream 等方法,只需替換對應的 decode* 呼叫。

最佳實踐總結

  1. 先用 inJustDecodeBounds=true 獲取原圖尺寸。
  2. 根據目標 View 大小計算 inSampleSize(2 的冪)。
  3. 設 inJustDecodeBounds=false 並重新解碼獲取縮放後 Bitmap。
  4. 配合 LRU 快取、非同步載入、圖片庫(Glide/Picasso)進一步優化體驗。

此技術是 Android 圖片載入優化的基石,掌握它能有效避免 OOM 並提升滾動性能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved