Reducing image size

2019-03-06 05:33发布

I am trying to reduce the size of an image that a user has selected from the Gallery before passing it to another intent.

I am currently using the following code, but it doesn't seem to be working:

private Bitmap decodeFile(File f) throws IOException {
    Bitmap b = null;

    //Decode image size
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;

    FileInputStream fis = null;
    fis = new FileInputStream(f);

    BitmapFactory.decodeStream(fis, null, o);
    fis.close();

    int scale = 1;
    if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
        scale = (int)Math.pow(2, (int) Math.ceil(Math.log(IMAGE_MAX_SIZE / 
           (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
    }

    //Decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    fis = new FileInputStream(f);
    b = BitmapFactory.decodeStream(fis, null, o2);
    fis.close();

    return b;
}

3条回答
手持菜刀,她持情操
2楼-- · 2019-03-06 06:21

The best way is pass the image path through the intent, then degrade the image from there. You do not need to degrade image on current activity and pass the degraded image.

Follow here in order to degrade your image read here. There Image quality will be reduced with the inSampleSize. Higher the inSampleSize will cause lower the image size.

查看更多
可以哭但决不认输i
3楼-- · 2019-03-06 06:26

You can use this code ...

public static Bitmap getThumbnailBitmap(final String path,
        final int thumbnailSize) {
    Bitmap bitmap;
    BitmapFactory.Options bounds = new BitmapFactory.Options();
    bounds.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(path, bounds);
    if ((bounds.outWidth == -1) || (bounds.outHeight == -1)) {
        bitmap = null;
    }
    int originalSize = (bounds.outHeight > bounds.outWidth) ? bounds.outHeight
            : bounds.outWidth;
    BitmapFactory.Options opts = new BitmapFactory.Options();
    if (thumbnailSize > 0) {
        opts.inSampleSize = originalSize / thumbnailSize;
    } else {
        opts.inSampleSize = originalSize;
    }
    try {
        bitmap = BitmapFactory.decodeFile(path, opts);

    } catch (Exception ex) {
        return null;
    }
    return bitmap;
}
查看更多
看我几分像从前
4楼-- · 2019-03-06 06:33

To Compress an Image you can use below code.

import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class ImageResizer {

    public static String getCompressImageFile(File original, int width, int height, String filePath) {
        Bitmap sampledSrcBitmap = decodeFile(original, width, height);

        if(sampledSrcBitmap == null) {
            return null;
        }
        Bitmap bitmap = getRotatedImage(sampledSrcBitmap,original.getPath());

        int bitmap_width = bitmap.getWidth();
        int bitmap_height = bitmap.getHeight();

        boolean success;
        if(bitmap_width<width && bitmap_height <height){
            success = writeToFile(bitmap, new File(filePath),100);
        }else{
            bitmap = resize(bitmap, width, height);
            success = writeToFile(bitmap, new File(filePath),80);
        }
        bitmap.recycle();
        if(success){
            return filePath;
        }else{
            return null;
        }
    }

    private static Bitmap getRotatedImage(Bitmap sampledSrcBitmap,String path){
        ExifInterface exif;
        Matrix matrix = new Matrix();
        Bitmap bitmap=null;
        try {
            exif = new ExifInterface(path);
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
            if (orientation == 6) {
                matrix.postRotate(90);
            } else if (orientation == 3) {
                matrix.postRotate(180);
            } else if (orientation == 8) {
                matrix.postRotate(270);
            }
            bitmap  = Bitmap.createBitmap(sampledSrcBitmap, 0, 0, sampledSrcBitmap.getWidth(), sampledSrcBitmap.getHeight(), matrix, true);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    public static Bitmap resize(Bitmap sampledSrcBitmap, int width, int height) {
        int sourceWidth = sampledSrcBitmap.getWidth();
        int sourceHeight = sampledSrcBitmap.getHeight();
        height = calculateHeight(sourceWidth, sourceHeight, width);
        return Bitmap.createScaledBitmap(sampledSrcBitmap, width, height, true);
    }

    private static int calculateWidth(int originalWidth, int originalHeight, int height) {
        return (int) Math.ceil(originalWidth / ((double) originalHeight/height));
    }

    private static int calculateHeight(int originalWidth, int originalHeight, int width) {
        return (int) Math.ceil(originalHeight / ((double) originalWidth/width));
    }

    public static Bitmap decodeFile(File bitmapFile, int reqWidth, int reqHeight){
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(bitmapFile.getAbsolutePath(), options);

        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        options.inDither = false;
        options.inPurgeable = true;
        options.inInputShareable = true;
        options.inPreferQualityOverSpeed = true;

        return BitmapFactory.decodeFile(bitmapFile.getAbsolutePath(), options);
    }

    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        if(reqWidth == -1) {
            reqWidth = options.outWidth;
        }

        if(reqHeight == -1) {
            reqHeight = options.outHeight;
        }

        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            if (width > height) {
                inSampleSize = Math.round((float) height / (float) reqHeight);
            } else {
                inSampleSize = Math.round((float) width / (float) reqWidth);
            }
        }

        return inSampleSize;
    }

    public static boolean writeToFile(Bitmap image, File file, int quality) {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        image.compress(CompressFormat.JPEG, quality, bytes);

        try {

            FileOutputStream fos = new FileOutputStream(file);
            fos.write(bytes.toByteArray());
            fos.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

}

And to get compress Image path call getComressImagePath method and give selected gallery image path for compression. Pass the compress image path to next activity where you can use it to upload to the server.

   public static String getComressImagePath(String picturePath){
         //Here 720 is max width and 1280 is max height. you can set this as per your need. Lower the resolution smaller the image size.
        return ImageResize.getCompressFile(new File(picturePath), 720, 1280, getTempImagePath());
   }

   public static String getTempImagePath(){
        File root = new File(Environment.getExternalStorageDirectory() + File.separator + "IMAGES");

        if (!root.exists()) {
            root.mkdirs();
        }

        File image = null;  
        image = new File(root+File.separator+"fileName");
        try {
           image.createNewFile();
           return image.getAbsolutePath();      
       } catch (IOException e) {
           e.printStackTrace();
       }

       return null;
   }
查看更多
登录 后发表回答