簡體   English   中英

嘗試壓縮位圖時出現OutOfMemoryError

[英]OutOfMemoryError when trying to compress bitmap

我正在使用android-crop庫。 如果用戶嘗試從大圖像(電話攝像頭的圖像)中裁剪,我將處理令人沮喪的內存不足異常。

我試圖壓縮結果位圖,但嘗試壓縮位圖時仍然出現OutOfMemoryError 這是我的代碼:請讓我知道我在做錯什么,和/或如何防止內存不足錯誤?

private void handleCrop(int resultCode, Intent result) {
    if (resultCode == RESULT_OK) {

        if (mBitmap != null) {
            mBitmap.recycle();
            mBitmap = null;
        }

        Bitmap temp; //temporary bitmap

        try {
            temp = MediaStore.Images.Media.getBitmap(getContentResolver()
                    , Crop.getOutput(result)); //load image from URI

            ByteArrayOutputStream out = new ByteArrayOutputStream();
            temp.compress(Bitmap.CompressFormat.JPEG, 60, out);
            mBitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));

            out.close();
            temp.recycle();
            temp = null;
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(this, "error loading photo. please try with another photo"
                    , Toast.LENGTH_SHORT).show();
            return;
        }

        if (mBitmap != null) {
            mImageViewProfilePhoto.setImageBitmap(mBitmap);
            enableFinalization();
        }

    }
}

感謝Gabe的觀點,我可以這樣解決問題:

private void handleCrop(int resultCode, Intent result) {
    if (resultCode == RESULT_OK) {

        if (mBitmap != null) {
            mBitmap.recycle();
            mBitmap = null;
        }

        try {
            mBitmap = MediaStore.Images.Media.getBitmap(getContentResolver()
                    , Crop.getOutput(result)); //load image from URI

            File tempImageFile = new File(mContext.getFilesDir().getAbsolutePath()
                    , "temp_1311_14_hahahah_lol_WTF_shit_1414.bin");

            FileOutputStream out = new FileOutputStream (tempImageFile);
            mBitmap.compress(Bitmap.CompressFormat.JPEG, 30, out);
            mBitmap.recycle();
            mBitmap = null;

            mBitmap = BitmapFactory.decodeFile(tempImageFile.getPath());
            boolean deleted = tempImageFile.delete();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(this, "error loading photo. please try with another photo"
                    , Toast.LENGTH_SHORT).show();
            return;
        }

        if (mBitmap != null) {
            mImageViewProfilePhoto.setImageBitmap(mBitmap);
            enableFinalization();
        }

    } else if (resultCode == Crop.RESULT_ERROR) {
        Toast.makeText(this, Crop.getError(result).getMessage(), Toast.LENGTH_SHORT).show();
        disableFinalization();
    }
}

希望對其他人有用。

假設問題不在應用程序的其他地方(而且OOM總是存在)-如果圖像較大,則基本上是制作3個副本。 第一個是原始的,第二個在您的ByteArrayOutputStream中,第三個在您的解碼流中。 如果圖像很大(例如10MB以上),則可能會引起問題。 我建議使用基於磁盤的輸出流,看看是否能使您解決問題。 另外,您還可以在temp.recycle之后放置decodeStream調用,以確保一次不會擁有2個完整副本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM