Reduce the size of a bitmap to a specified size in Android

前端 未结 2 1815
生来不讨喜
生来不讨喜 2020-12-08 19:58

I want to reduce the size of a bitmap to 200kb exactly. I get an image from the sdcard, compress it and save it to the sdcard again with a different name into a different di

相关标签:
2条回答
  • 2020-12-08 20:19

    Here is the solution that limits image quality without changing width and height. The main idea of this approach is to compress bitmap inside the loop while output size is bigger than maxSizeBytesCount. Credits to this question for the answer. This code block shows only the logic of reducing image quality:

            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            int currSize;
            int currQuality = 100;
    
            do {
                bitmap.compress(Bitmap.CompressFormat.JPEG, currQuality, stream);
                currSize = stream.toByteArray().length;
                // limit quality by 5 percent every time
                currQuality -= 5;
    
            } while (currSize >= maxSizeBytes);
    

    Here is the full method:

    public class ImageUtils {
    
        public byte[] compressBitmap(
                String file, 
                int width, 
                int height,
                int maxSizeBytes
        ) {
            BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
            bmpFactoryOptions.inJustDecodeBounds = true;
            Bitmap bitmap;
    
            int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
            int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);
    
            if (heightRatio > 1 || widthRatio > 1)
            {
                if (heightRatio > widthRatio)
                {
                    bmpFactoryOptions.inSampleSize = heightRatio;
                } else {
                    bmpFactoryOptions.inSampleSize = widthRatio;
                }
            }
    
            bmpFactoryOptions.inJustDecodeBounds = false;
            bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);
    
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            int currSize;
            int currQuality = 100;
    
            do {
                bitmap.compress(Bitmap.CompressFormat.JPEG, currQuality, stream);
                currSize = stream.toByteArray().length;
                // limit quality by 5 percent every time
                currQuality -= 5;
    
            } while (currSize >= maxSizeBytes);
    
            return stream.toByteArray();
        }
    }
    
    0 讨论(0)
  • 2020-12-08 20:23

    I found an answer that works perfectly for me:

    /**
     * reduces the size of the image
     * @param image
     * @param maxSize
     * @return
     */
    public Bitmap getResizedBitmap(Bitmap image, int maxSize) {
        int width = image.getWidth();
        int height = image.getHeight();
    
        float bitmapRatio = (float)width / (float) height;
        if (bitmapRatio > 1) {
            width = maxSize;
            height = (int) (width / bitmapRatio);
        } else {
            height = maxSize;
            width = (int) (height * bitmapRatio);
        }
        return Bitmap.createScaledBitmap(image, width, height, true);
    }
    

    calling the method:

    Bitmap converetdImage = getResizedBitmap(photo, 500);
    

    Where photo is your bitmap

    0 讨论(0)
提交回复
热议问题