android開發步步為營之50:android關於載入大圖片java.lang.OutOfMemoryError錯誤的解決

來源:互聯網
上載者:User

標籤:android   outofmemoryerror   




http://developer.android.com/training/displaying-bitmaps/load-bitmap.html 官方有一篇文章是如下這麼解決的,通過Resource載入後壓縮圖片大小
//方法一:通過Resource載入

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

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

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;
}
如果不是通過Resource,而是通過Drawable對象,比如擷取手機所有安裝的應用表徵圖,通過下面這張方法來壓縮圖片

//方法二:通過Drawable對象載入
//擷取壓縮後的表徵圖
    private Drawable getAppIcon(PackageManager pm, ApplicationInfo applicationInfo) {
        try {
            //oom報錯,採用下面的方法
            Drawable drawable = pm.getApplicationIcon(applicationInfo);
            Bitmap bm = CommonUtils.drawableToBitmap(drawable);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
            byte[] data = baos.toByteArray();
             //壓縮前
            int size1=bm.getByteCount();
            BitmapFactory.Options opts = new BitmapFactory.Options();
            opts.inJustDecodeBounds = true;   
            BitmapFactory.decodeByteArray(data, 0, data.length, opts); 
            opts.inSampleSize = computeSampleSize(opts, -1, 100 * 100);
            //這裡一定要將其設定回false,因為之前我們將其設定成了true     
            opts.inJustDecodeBounds = false;
            Bitmap bmNew =BitmapFactory.decodeByteArray(data, 0, data.length, opts);
            //壓縮後,測試過4194304Byte的壓縮成16384Byte壓縮效果明顯
            int size2=bmNew.getByteCount();
           
            return new BitmapDrawable(bmNew);

            //end    
        }catch(Exception e)
        {
            Log.e("DataCenter.getAppIcon.Exception", "Exception", e);
        }
        catch (OutOfMemoryError e) {
            // TODO: handle exception
            Log.e("DataCenter.getAppIcon.OutOfMemoryError", "OutOfMemoryError", e);
            //圖片太大就換一個預設的小表徵圖給使用者
            return new BitmapDrawable(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher_default));
        }
        return null;
    }

  public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
        int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);
        int roundedSize;
        if (initialSize <= 8) {
            roundedSize = 1;
            while (roundedSize < initialSize) {
                roundedSize <<= 1;
            }
        } else {
            roundedSize = (initialSize + 7) / 8 * 8;
        }
        return roundedSize;
    }

    private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
        double w = options.outWidth;
        double h = options.outHeight;
        int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
        int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));
        if (upperBound < lowerBound) {
            return lowerBound;
        }
        if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
            return 1;
        } else if (minSideLength == -1) {
            return lowerBound;
        } else {
            return upperBound;
        }
    }

    public static Bitmap drawableToBitmap(Drawable drawable) {
        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                : Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(bitmap);
        //canvas.setBitmap(bitmap);
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        drawable.draw(canvas);
        return bitmap;

    }


BitmapFactory提供多種Decode方法,大家根據需要來使用

android開發步步為營之50:android關於載入大圖片java.lang.OutOfMemoryError錯誤的解決

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.