OutOfMemoryError while decoding and encoding Base64 String into Bitmap

前端 未结 7 1997
你的背包
你的背包 2020-12-14 14:49

I\'m trying to decode and encode a Bitmap image. On some devices it runs perfectly while on others it\'s not. I\'m uploading Bas

7条回答
  •  执念已碎
    2020-12-14 15:22

    You can try this, it should solve your problem.

    Basically first saving the data to a file, using a buffer to avoid memory problems. After that we check and resize the file - loading directly a resized Bitmap, again to avoid memory problems.

    From what I can suppose, you are getting the encoded string from a server... so you can manage your code to directly write to the file.

    Writing the data to the file:

    private Bitmap getBitmapThumbnail(String base64StringReceive) {
            byte[] data = Base64.decode(base64StringReceive, Base64.DEFAULT);
            File file = new File(getFilesDir(), "testFile");
    
            try {
                BufferedOutputStream bos = new BufferedOutputStream(openFileOutput("testFile", Context.MODE_PRIVATE),1024);
                bos.write(data);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return getThumbFromFile(file, false);
        }
    

    Creating the thumbnail from the image file:

    private Bitmap getThumbFromFile(File file) {
        Bitmap tempImage = null;
        try {
            tempImage = decodeSampledBitmapFromFile(file.getAbsolutePath(), 50, 50); // this is in pixels - use your desired size
            return ThumbnailUtils.extractThumbnail(tempImage, 50, 50);
        } finally {
            if (tempImage != null) {
                tempImage.recycle();
            }
        }
    }
    

    Loading only a resized Bitmap:

    private Bitmap decodeSampledBitmapFromFile(String filePath, int reqWidth, int reqHeight) {
        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);
    
        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(filePath, options);
    }
    

    Calculating the sampling value - provided by Google, you can find it their tutorials:

    private 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;
    }
    

提交回复
热议问题