Android, Compressing an image

2020-03-26 08:13发布

问题:

I am sending an image over the network via wifi or the mobile network to be stored in a server and retrieved again. I've done that but due to the size of images taken by the camera it's making my app slow, just to point out I'm opening the gallery and taking the pictures from there and not taking the picture directly from the app. I have noticed that images from whatsapp that have been taken from the camera and gallery have been compressed to approx. 100kb.

At the moment my code takes a file and converts it to bytes and then sends it. Here is the method for taking a file and converting it to bytes.

private void toBytes(String filePath){
    try{
        File file = new File(filePath);
        InputStream is = new BufferedInputStream(new FileInputStream(file));  
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        bytes = new byte[(int) filePath.length()];
        int bytes_read;
        while((bytes_read = is.read(bytes, 0, bytes.length)) != -1){
            buffer.write(bytes, 0, bytes_read);
        }
        is.close();               
        bytes = buffer.toByteArray();
    }catch(Exception err){
        Toast.makeText(getApplicationContext(), err.toString(), Toast.LENGTH_SHORT).show();
    }
}

So my question is how would I go about compressing my image before sending? Also I don't need the image to retain a high pixel count as when the app uses the image it will only take up half of the devices screen.

Thank you for any help given.

回答1:

The BitMap http://developer.android.com/reference/android/graphics/Bitmap.html class have a compress method. But you might need to scale the image createScaledBitmap, also available in the same class.



回答2:

Try using the following method:

    //decodes image and scales it to reduce memory consumption
    //NOTE: if the image has dimensions which exceed int width and int height
    //its dimensions will be altered.
    private Bitmap decodeToLowResImage(byte [] b, int width, int height) {
        try {
            //Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new ByteArrayInputStream(b), null, o);

            //The new size we want to scale to
            final int REQUIRED_SIZE_WIDTH=(int)(width*0.7);
            final int REQUIRED_SIZE_HEIGHT=(int)(height*0.7);

            //Find the correct scale value. It should be the power of 2.
            int width_tmp=o.outWidth, height_tmp=o.outHeight;
            int scale=1;
            while(true){
                if(width_tmp/2<REQUIRED_SIZE_WIDTH || height_tmp/2<REQUIRED_SIZE_HEIGHT)
                    break;
                width_tmp/=2;
                height_tmp/=2;
                scale*=2;
            }

            //Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize=scale;
            return BitmapFactory.decodeStream(new ByteArrayInputStream(b), null, o2);
        } catch (OutOfMemoryError e) {
        }
        return null;
    }


回答3:

The Android library named SiliCompressor have been optimized to do all the image compression for you. Check it on Github