How to compress image size?
Asked Answered
F

13

42

I want to capture image in low resolution using android camera api but when I captured image it will take default resolution of device camera.So I want to capture image in low resolution or small size at time of capture or how can I compress big image into small size in android?

Foxtrot answered 31/8, 2013 at 6:28 Comment(1)
mindbowser.com/image-compression-in-androidOccam
S
32

You can create bitmap with captured image as below:

Bitmap bitmap = Bitmap.createScaledBitmap(capturedImage, width, height, true);

Here you can specify width and height of the bitmap that you want to set to your ImageView. The height and width you can set according to the screen dpi of the device also, by reading the screen dpi of different devices programmatically.

Strepphon answered 31/8, 2013 at 6:38 Comment(1)
Yeah but is there a way without scaling? It makes the image look weirdClientele
D
31

Use Compressor (Image compression library). Visit zetbaitsu/Compressor for code and documentation.

  1. add dependency in gradle (app level)

    dependencies {
        implementation 'id.zelory:compressor:3.0.0'
    }
    
  2. To Compress Image use one of these approaches:

  • Compress Image File:

          val compressedImageFile = Compressor.compress(context, actualImageFile)
    
  • Compress Image File to Bitmap:

          val compressedImageFile = Compressor.compress(context, actualImageFile)
          val bitmap = BitmapFactory.decodeFile(compressedImageFile.path)
    
Debouch answered 10/7, 2017 at 9:55 Comment(5)
getting error "Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference" sir pleas help me...Natalya
how can i use this library for java?? Can you please also write the code for javaGanesa
implementation 'id.zelory:compressor:2.1.1' For JAVA github.com/zetbaitsu/Compressor/blob/master/README_v2.mdClaqueur
@Claqueur - exception shows as Compressor has private!Phocomelia
Bitmap is to wasteful use a compression format like the superior WebP, from Google, instead.Epigastrium
B
11

Try this is working great with me.

private String decodeFile(String path) {
        String strMyImagePath = null;
        Bitmap scaledBitmap = null;

        try {
            // Part 1: Decode image
            Bitmap unscaledBitmap = ScalingUtilities.decodeFile(path, DESIREDWIDTH, DESIREDHEIGHT, ScalingLogic.FIT);

            if (!(unscaledBitmap.getWidth() <= 800 && unscaledBitmap.getHeight() <= 800)) {
                // Part 2: Scale image
                scaledBitmap = ScalingUtilities.createScaledBitmap(unscaledBitmap, DESIREDWIDTH, DESIREDHEIGHT, ScalingLogic.FIT);
            } else {
                unscaledBitmap.recycle();
                return path;
            }

            // Store to tmp file

            String extr = Environment.getExternalStorageDirectory().toString();
            File mFolder = new File(extr + "/myTmpDir");
            if (!mFolder.exists()) {
                mFolder.mkdir();
            }

            String s = "tmp.png";

            File f = new File(mFolder.getAbsolutePath(), s);

            strMyImagePath = f.getAbsolutePath();
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(f);
                scaledBitmap.compress(Bitmap.CompressFormat.PNG, 70, fos);
                fos.flush();
                fos.close();
            } catch (FileNotFoundException e) {

                e.printStackTrace();
            } catch (Exception e) {

                e.printStackTrace();
            }

            scaledBitmap.recycle();
        } catch (Throwable e) {
        }

        if (strMyImagePath == null) {
            return path;
        }
        return strMyImagePath;

    }

Utility Class

public class ScalingUtilities {

    /**
     * Utility function for decoding an image resource. The decoded bitmap will
     * be optimized for further scaling to the requested destination dimensions
     * and scaling logic.
     *
     * @param res The resources object containing the image data
     * @param resId The resource id of the image data
     * @param dstWidth Width of destination area
     * @param dstHeight Height of destination area
     * @param scalingLogic Logic to use to avoid image stretching
     * @return Decoded bitmap
     */
    public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight,
            ScalingLogic scalingLogic) {
        Options options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
        options.inJustDecodeBounds = false;
        options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
                dstHeight, scalingLogic);
        Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);

        return unscaledBitmap;
    }
    public static Bitmap decodeFile(String path, int dstWidth, int dstHeight,
            ScalingLogic scalingLogic) {
        Options options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);
        options.inJustDecodeBounds = false;
        options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
                dstHeight, scalingLogic);
        Bitmap unscaledBitmap = BitmapFactory.decodeFile(path, options);

        return unscaledBitmap;
    }

    /**
     * Utility function for creating a scaled version of an existing bitmap
     *
     * @param unscaledBitmap Bitmap to scale
     * @param dstWidth Wanted width of destination bitmap
     * @param dstHeight Wanted height of destination bitmap
     * @param scalingLogic Logic to use to avoid image stretching
     * @return New scaled bitmap object
     */
    public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight,
            ScalingLogic scalingLogic) {
        Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
                dstWidth, dstHeight, scalingLogic);
        Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
                dstWidth, dstHeight, scalingLogic);
        Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(),
                Config.ARGB_8888);
        Canvas canvas = new Canvas(scaledBitmap);
        canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));

        return scaledBitmap;
    }

    /**
     * ScalingLogic defines how scaling should be carried out if source and
     * destination image has different aspect ratio.
     *
     * CROP: Scales the image the minimum amount while making sure that at least
     * one of the two dimensions fit inside the requested destination area.
     * Parts of the source image will be cropped to realize this.
     *
     * FIT: Scales the image the minimum amount while making sure both
     * dimensions fit inside the requested destination area. The resulting
     * destination dimensions might be adjusted to a smaller size than
     * requested.
     */
    public static enum ScalingLogic {
        CROP, FIT
    }

    /**
     * Calculate optimal down-sampling factor given the dimensions of a source
     * image, the dimensions of a destination area and a scaling logic.
     *
     * @param srcWidth Width of source image
     * @param srcHeight Height of source image
     * @param dstWidth Width of destination area
     * @param dstHeight Height of destination area
     * @param scalingLogic Logic to use to avoid image stretching
     * @return Optimal down scaling sample size for decoding
     */
    public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
            ScalingLogic scalingLogic) {
        if (scalingLogic == ScalingLogic.FIT) {
            final float srcAspect = (float)srcWidth / (float)srcHeight;
            final float dstAspect = (float)dstWidth / (float)dstHeight;

            if (srcAspect > dstAspect) {
                return srcWidth / dstWidth;
            } else {
                return srcHeight / dstHeight;
            }
        } else {
            final float srcAspect = (float)srcWidth / (float)srcHeight;
            final float dstAspect = (float)dstWidth / (float)dstHeight;

            if (srcAspect > dstAspect) {
                return srcHeight / dstHeight;
            } else {
                return srcWidth / dstWidth;
            }
        }
    }

    /**
     * Calculates source rectangle for scaling bitmap
     *
     * @param srcWidth Width of source image
     * @param srcHeight Height of source image
     * @param dstWidth Width of destination area
     * @param dstHeight Height of destination area
     * @param scalingLogic Logic to use to avoid image stretching
     * @return Optimal source rectangle
     */
    public static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
            ScalingLogic scalingLogic) {
        if (scalingLogic == ScalingLogic.CROP) {
            final float srcAspect = (float)srcWidth / (float)srcHeight;
            final float dstAspect = (float)dstWidth / (float)dstHeight;

            if (srcAspect > dstAspect) {
                final int srcRectWidth = (int)(srcHeight * dstAspect);
                final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
                return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight);
            } else {
                final int srcRectHeight = (int)(srcWidth / dstAspect);
                final int scrRectTop = (int)(srcHeight - srcRectHeight) / 2;
                return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight);
            }
        } else {
            return new Rect(0, 0, srcWidth, srcHeight);
        }
    }

    /**
     * Calculates destination rectangle for scaling bitmap
     *
     * @param srcWidth Width of source image
     * @param srcHeight Height of source image
     * @param dstWidth Width of destination area
     * @param dstHeight Height of destination area
     * @param scalingLogic Logic to use to avoid image stretching
     * @return Optimal destination rectangle
     */
    public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
            ScalingLogic scalingLogic) {
        if (scalingLogic == ScalingLogic.FIT) {
            final float srcAspect = (float)srcWidth / (float)srcHeight;
            final float dstAspect = (float)dstWidth / (float)dstHeight;

            if (srcAspect > dstAspect) {
                return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect));
            } else {
                return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight);
            }
        } else {
            return new Rect(0, 0, dstWidth, dstHeight);
        }
    }

}
Bowdlerize answered 31/8, 2013 at 6:33 Comment(3)
here Scalling logic means ?Commercial
Two type : FIX is for it will stretch the image to fit the given size. CROP is for it will crop image from the center without stretch the image to fit the given sizeBowdlerize
@BirajZalavadia This is working just fine, except that the image gets rotated when I save it in the temporary folder. How can I make it not rotate?Reluctance
O
7

You can compress image bitmap like this way.

ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);

Here 100 is quality of image and you can change format of image to get low resolution image.

Overplay answered 31/8, 2013 at 6:31 Comment(5)
but this compress method is not working for me..I am saving image in JPEG format.is that format problem?Foxtrot
thnx..but i want samll size image which I can pload to serverFoxtrot
you can set height and width as per @mAndroid's answer.Overplay
It doesn't work for me too, have you found the solution to this?Studer
Bitmap is to wasteful use a compression format like the superior WebP, from Google, instead. Same quality but smaller space.Epigastrium
A
2

I think you are asking about Shrinking image size:

    public Bitmap ShrinkBitmap(String file, int width, int height)
{
    BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
    bmpFactoryOptions.inJustDecodeBounds = true;
    Bitmap bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);

    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);
    return bitmap;
}
Anglosaxon answered 15/4, 2014 at 11:11 Comment(2)
(name of a method should be in camelcase)Husha
Bitmap is to wasteful use a compression format like the superior WebP, from Google, instead. Same quality but smaller space.Epigastrium
B
2

please have look at compressImage method i have used for compressing image.

public static String compressImage(String imageUri, Activity activity) {
    String filename = "";
    try {
        String filePath = getRealPathFromURI(imageUri, activity);
        Bitmap scaledBitmap = null;

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        Bitmap bmp = BitmapFactory.decodeFile(filePath, options);

        int actualHeight = options.outHeight;
        int actualWidth = options.outWidth;
        float maxHeight = 816.0f;
        float maxWidth = 612.0f;
        float imgRatio = actualWidth / actualHeight;
        float maxRatio = maxWidth / maxHeight;

        if (actualHeight > maxHeight || actualWidth > maxWidth) {
            if (imgRatio < maxRatio) {
                imgRatio = maxHeight / actualHeight;
                actualWidth = (int) (imgRatio * actualWidth);
                actualHeight = (int) maxHeight;
            } else if (imgRatio > maxRatio) {
                imgRatio = maxWidth / actualWidth;
                actualHeight = (int) (imgRatio * actualHeight);
                actualWidth = (int) maxWidth;
            } else {
                actualHeight = (int) maxHeight;
                actualWidth = (int) maxWidth;

            }
        }

        options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
        options.inJustDecodeBounds = false;
        options.inDither = false;
        options.inPurgeable = true;
        options.inInputShareable = true;
        options.inTempStorage = new byte[16 * 1024];

        try {
            bmp = BitmapFactory.decodeFile(filePath, options);
        } catch (OutOfMemoryError exception) {
            exception.printStackTrace();

        }
        try {
            scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
        } catch (OutOfMemoryError exception) {
            exception.printStackTrace();
        }

        float ratioX = actualWidth / (float) options.outWidth;
        float ratioY = actualHeight / (float) options.outHeight;
        float middleX = actualWidth / 2.0f;
        float middleY = actualHeight / 2.0f;

        Matrix scaleMatrix = new Matrix();
        scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

        Canvas canvas;
        if (scaledBitmap != null) {
            canvas = new Canvas(scaledBitmap);
            canvas.setMatrix(scaleMatrix);
            canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
        }


        ExifInterface exif;
        try {
            exif = new ExifInterface(filePath);

            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);

            Matrix matrix = new Matrix();
            if (orientation == 6) {
                matrix.postRotate(90);

            } else if (orientation == 3) {
                matrix.postRotate(180);

            } else if (orientation == 8) {
                matrix.postRotate(270);

            }
            if (scaledBitmap != null) {
                scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        FileOutputStream out;
        filename = getFilename(activity);
        try {
            out = new FileOutputStream(filename);
            if (scaledBitmap != null) {
                scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    return filename;
}

private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {
        final int heightRatio = Math.round((float) height / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }
    final float totalPixels = width * height;
    final float totalReqPixelsCap = reqWidth * reqHeight * 2;

    while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
        inSampleSize++;
    }

    return inSampleSize;
}

private static String getRealPathFromURI(String contentURI, Activity activity) {
    Uri contentUri = Uri.parse(contentURI);
    Cursor cursor = activity.getContentResolver().query(contentUri, null, null, null, null);
    if (cursor == null) {
        return contentUri.getPath();
    } else {
        cursor.moveToFirst();
        int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
        return cursor.getString(idx);
    }
}
Berube answered 29/3, 2018 at 13:54 Comment(2)
Can you please explain your code in short @Neelesh AtaleCustomer
Bitmap is to wasteful use a compression format like the superior WebP, from Google, instead. Same quality but smaller space.Epigastrium
C
1

Try this one:

byte[] data = null;

ByteArrayOutputStream baos = new ByteArrayOutputStream();
bi.compress(Bitmap.CompressFormat.JPEG, 100, baos);

data = baos.toByteArray();
Chickaree answered 31/8, 2013 at 6:49 Comment(0)
D
1

You can use this awesome library to compress. Add dependency in app-level gradel:

    dependencies {
    implementation 'id.zelory:compressor:3.0.0'
}

And then just compress the actual image file like this:

val compressedImageFile = Compressor.compress(context, actualImageFile)
Dyl answered 28/7, 2020 at 19:6 Comment(1)
can i use this in Java??Ganesa
E
1

You should use Googles native image format WebP, it will shrink the image without losing quality. You can compress 80% of the picture without losing quality.

enter image description here

You can use CompressFormat.WEBP to encode any bitmap in WEBP format.

Example from file:

const int quality = 100; 
FileOutputStream out = new FileOutputStream(path); 
bitmap.compress(Bitmap.CompressFormat.WEBP, quality, out);
out.close(); 
Epigastrium answered 28/7, 2020 at 19:40 Comment(0)
P
0

i resolve this problem in this way, later i will improve the code

protected Void doInBackground(byte[]... data) {
        FileOutputStream outStream = null;

        // Write to Internal Storage
        try {
            File dir = new File (context.getFilesDir());
            dir.mkdirs();

            String fileName ="image.jpg";
            File outFile = new File(dir, fileName);
            outFile.setExecutable(true, false);
            outFile.setWritable(true, false);
            outStream = new FileOutputStream(outFile);
            outStream.write(data[0]);
            outStream.flush();
            outStream.close();
            InputStream in = new FileInputStream(context.getFilesDir()+"image.jpg");
            Bitmap bm2 = BitmapFactory.decodeStream(in);
            OutputStream stream = new FileOutputStream(String.valueOf(context.getFilesDir()+pathImage+"/"+idPicture+".jpg"));
            bm2.compress(Bitmap.CompressFormat.JPEG, 50, stream);
            stream.close();
            in.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
        return null;
    }
Pitch answered 18/7, 2016 at 21:2 Comment(0)
O
0

use this class to compress image

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.Paint
import android.net.Uri
import android.os.Environment
import java.io.*


class ImageFile(val uri: Uri, name: String) {

    val filename: String

    init {
        val file = File(Environment.getExternalStorageDirectory().toString() + "/Documents")
        if (!file.exists()) {
            file.mkdirs()
        }
        val fileNoMedia = File(file.absolutePath + "/.nomedia")
        if (!fileNoMedia.exists())
            fileNoMedia.createNewFile()
        if (name.toLowerCase().endsWith(".pdf")) {
            filename = file.absolutePath + "/" + System.currentTimeMillis() + ".pdf"
        } else {
            filename = file.absolutePath + "/" + System.currentTimeMillis() + ".jpg"
        }
    }

    @Throws(IOException::class)
    fun copyFileStream(context: Context, uri: Uri): String {
        if (filename.endsWith(".pdf") || filename.endsWith(".PDF")) {
            var ins: InputStream? = null
            var os: OutputStream? = null
            try {
                ins = context.getContentResolver().openInputStream(uri)
                os = FileOutputStream(filename)
                val buffer = ByteArray(1024)
                var length: Int = ins.read(buffer)
                while (length > 0) {
                    os.write(buffer, 0, length);
                    length = ins.read(buffer)
                }
            } catch (e: Exception) {
                e.printStackTrace();
            } finally {
                ins?.close()
                os?.close()
            }
        } else {
            var ins: InputStream? = null
            var os: OutputStream? = null
            try {
                ins = context.getContentResolver().openInputStream(uri)
                var scaledBitmap: Bitmap? = null
                val options = BitmapFactory.Options()
                options.inJustDecodeBounds = true
                var bmp = BitmapFactory.decodeStream(ins, null, options)
                var actualHeight = options.outHeight
                var actualWidth = options.outWidth

                //      max Height and width values of the compressed image is taken as 816x612
                val maxHeight = 816.0f
                val maxWidth = 612.0f
                var imgRatio = (actualWidth / actualHeight).toFloat()
                val maxRatio = maxWidth / maxHeight

                //      width and height values are set maintaining the aspect ratio of the image
                if (actualHeight > maxHeight || actualWidth > maxWidth) {
                    if (imgRatio < maxRatio) {
                        imgRatio = maxHeight / actualHeight
                        actualWidth = (imgRatio * actualWidth).toInt()
                        actualHeight = maxHeight.toInt()
                    } else if (imgRatio > maxRatio) {
                        imgRatio = maxWidth / actualWidth
                        actualHeight = (imgRatio * actualHeight).toInt()
                        actualWidth = maxWidth.toInt()
                    } else {
                        actualHeight = maxHeight.toInt()
                        actualWidth = maxWidth.toInt()

                    }
                }

                //      setting inSampleSize value allows to load a scaled down version of the original image
                options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight)

                //      inJustDecodeBounds set to false to load the actual bitmap
                options.inJustDecodeBounds = false

                //      this options allow android to claim the bitmap memory if it runs low on memory
                options.inPurgeable = true
                options.inInputShareable = true
                options.inTempStorage = ByteArray(16 * 1024)


                try {
                    //          load the bitmap from its path
                    ins.close()
                    ins = context.getContentResolver().openInputStream(uri)
                    bmp = BitmapFactory.decodeStream(ins, null, options)
                } catch (exception: OutOfMemoryError) {
                    exception.printStackTrace()

                }

                try {
                    scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888)
                } catch (exception: OutOfMemoryError) {
                    exception.printStackTrace()
                }

                val ratioX = actualWidth / options.outWidth.toFloat()
                val ratioY = actualHeight / options.outHeight.toFloat()
                val middleX = actualWidth / 2.0f
                val middleY = actualHeight / 2.0f

                val scaleMatrix = Matrix()
                scaleMatrix.setScale(ratioX, ratioY, middleX, middleY)

                val canvas = Canvas(scaledBitmap!!)
                canvas.matrix = scaleMatrix
                canvas.drawBitmap(bmp, middleX - bmp.width / 2, middleY - bmp.height / 2, Paint(Paint.FILTER_BITMAP_FLAG))

                os = FileOutputStream(filename)
                scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, os)
                val buffer = ByteArray(1024)
                var length: Int = ins.read(buffer)
                while (length > 0) {
                    os.write(buffer, 0, length);
                    length = ins.read(buffer)
                }
            } catch (e: Exception) {
                e.printStackTrace();
            } finally {
                ins?.close()
                os?.close()
            }
        }
        return filename
    }

    fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
        val height = options.outHeight
        val width = options.outWidth
        var inSampleSize = 1
        if (height > reqHeight || width > reqWidth) {
            val heightRatio = Math.round(height.toFloat() / reqHeight.toFloat())
            val widthRatio = Math.round(width.toFloat() / reqWidth.toFloat())
            inSampleSize = if (heightRatio < widthRatio) heightRatio else widthRatio
        }
        val totalPixels = (width * height).toFloat()
        val totalReqPixelsCap = (reqWidth * reqHeight * 2).toFloat()
        while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
            inSampleSize++
        }

        return inSampleSize
    }
}

https://lalitjadav007.blogspot.in/2017/08/compress-image-in-android.html

Overshoe answered 4/10, 2017 at 7:18 Comment(0)
R
0

You can try this code

    public class ScalingUtilities {

    /**
     * Utility function for decoding an image resource. The decoded bitmap will
     * be optimized for further scaling to the requested destination dimensions
     * and scaling logic.
     *
     * @param res The resources object containing the image data
     * @param resId The resource id of the image data
     * @param dstWidth Width of destination area
     * @param dstHeight Height of destination area
     * @param scalingLogic Logic to use to avoid image stretching
     * @return Decoded bitmap
     */
    public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight,
            ScalingLogic scalingLogic) {
        Options options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
        options.inJustDecodeBounds = false;
        options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
                dstHeight, scalingLogic);
        Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);

        return unscaledBitmap;
    }
    public static Bitmap decodeFile(String path, int dstWidth, int dstHeight,
            ScalingLogic scalingLogic) {
        Options options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);
        options.inJustDecodeBounds = false;
        options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
                dstHeight, scalingLogic);
        Bitmap unscaledBitmap = BitmapFactory.decodeFile(path, options);

        return unscaledBitmap;
    }

    /**
     * Utility function for creating a scaled version of an existing bitmap
     *
     * @param unscaledBitmap Bitmap to scale
     * @param dstWidth Wanted width of destination bitmap
     * @param dstHeight Wanted height of destination bitmap
     * @param scalingLogic Logic to use to avoid image stretching
     * @return New scaled bitmap object
     */
    public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight,
            ScalingLogic scalingLogic) {
        Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
                dstWidth, dstHeight, scalingLogic);
        Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
                dstWidth, dstHeight, scalingLogic);
        Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(),
                Config.ARGB_8888);
        Canvas canvas = new Canvas(scaledBitmap);
        canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));

        return scaledBitmap;
    }

    /**
     * ScalingLogic defines how scaling should be carried out if source and
     * destination image has different aspect ratio.
     *
     * CROP: Scales the image the minimum amount while making sure that at least
     * one of the two dimensions fit inside the requested destination area.
     * Parts of the source image will be cropped to realize this.
     *
     * FIT: Scales the image the minimum amount while making sure both
     * dimensions fit inside the requested destination area. The resulting
     * destination dimensions might be adjusted to a smaller size than
     * requested.
     */
    public static enum ScalingLogic {
        CROP, FIT
    }

    /**
     * Calculate optimal down-sampling factor given the dimensions of a source
     * image, the dimensions of a destination area and a scaling logic.
     *
     * @param srcWidth Width of source image
     * @param srcHeight Height of source image
     * @param dstWidth Width of destination area
     * @param dstHeight Height of destination area
     * @param scalingLogic Logic to use to avoid image stretching
     * @return Optimal down scaling sample size for decoding
     */
    public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
            ScalingLogic scalingLogic) {
        if (scalingLogic == ScalingLogic.FIT) {
            final float srcAspect = (float)srcWidth / (float)srcHeight;
            final float dstAspect = (float)dstWidth / (float)dstHeight;

            if (srcAspect > dstAspect) {
                return srcWidth / dstWidth;
            } else {
                return srcHeight / dstHeight;
            }
        } else {
            final float srcAspect = (float)srcWidth / (float)srcHeight;
            final float dstAspect = (float)dstWidth / (float)dstHeight;

            if (srcAspect > dstAspect) {
                return srcHeight / dstHeight;
            } else {
                return srcWidth / dstWidth;
            }
        }
    }

    /**
     * Calculates source rectangle for scaling bitmap
     *
     * @param srcWidth Width of source image
     * @param srcHeight Height of source image
     * @param dstWidth Width of destination area
     * @param dstHeight Height of destination area
     * @param scalingLogic Logic to use to avoid image stretching
     * @return Optimal source rectangle
     */
    public static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
            ScalingLogic scalingLogic) {
        if (scalingLogic == ScalingLogic.CROP) {
            final float srcAspect = (float)srcWidth / (float)srcHeight;
            final float dstAspect = (float)dstWidth / (float)dstHeight;

            if (srcAspect > dstAspect) {
                final int srcRectWidth = (int)(srcHeight * dstAspect);
                final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
                return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight);
            } else {
                final int srcRectHeight = (int)(srcWidth / dstAspect);
                final int scrRectTop = (int)(srcHeight - srcRectHeight) / 2;
                return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight);
            }
        } else {
            return new Rect(0, 0, srcWidth, srcHeight);
        }
    }

    /**
     * Calculates destination rectangle for scaling bitmap
     *
     * @param srcWidth Width of source image
     * @param srcHeight Height of source image
     * @param dstWidth Width of destination area
     * @param dstHeight Height of destination area
     * @param scalingLogic Logic to use to avoid image stretching
     * @return Optimal destination rectangle
     */
    public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
            ScalingLogic scalingLogic) {
        if (scalingLogic == ScalingLogic.FIT) {
            final float srcAspect = (float)srcWidth / (float)srcHeight;
            final float dstAspect = (float)dstWidth / (float)dstHeight;

            if (srcAspect > dstAspect) {
                return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect));
            } else {
                return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight);
            }
        } else {
            return new Rect(0, 0, dstWidth, dstHeight);
        }
    }


    public static String decodeFile(String path,int DESIREDWIDTH, int DESIREDHEIGHT, int type) {
        String strMyImagePath = null;
        Bitmap scaledBitmap = null;
        Bitmap rotated = null;

        try {
            // Part 1: Decode image
            Bitmap unscaledBitmap = ScalingUtilities.decodeFile(path, DESIREDWIDTH, DESIREDHEIGHT, ScalingLogic.FIT);

//            if (!(unscaledBitmap.getWidth() <= DESIREDWIDTH && unscaledBitmap.getHeight() <= DESIREDHEIGHT)) {
//                // Part 2: Scale image
//                scaledBitmap = ScalingUtilities.createScaledBitmap(unscaledBitmap, DESIREDWIDTH, DESIREDHEIGHT, ScalingLogic.FIT);
//            } else {
//                unscaledBitmap.recycle();
//                return path;
//            }

            // Store to tmp file
            scaledBitmap = ScalingUtilities.createScaledBitmap(unscaledBitmap, DESIREDWIDTH, DESIREDHEIGHT, ScalingLogic.FIT);

            String extr = Environment.getExternalStorageDirectory().toString();
            File mFolder = new File(extr + com.vt.vsmart.utils.Config.SD_PATH+"/image");
            if (!mFolder.exists()) {
                mFolder.mkdir();
            }

            String s = type+"temp.jpg";

            File f = new File(mFolder.getAbsolutePath(), s);

            strMyImagePath = f.getAbsolutePath();
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(f);
//                scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 95, fos);

                // quay anh 90 do
                Matrix matrix = new Matrix();

                matrix.postRotate(90);

                rotated = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);

                rotated.compress(Bitmap.CompressFormat.JPEG, 95, fos);

                fos.flush();
                fos.close();
            } catch (FileNotFoundException e) {

                e.printStackTrace();
            } catch (Exception e) {

                e.printStackTrace();
            }

//            scaledBitmap.recycle();
            rotated.recycle();
        } catch (Throwable e) {
        }

        if (strMyImagePath == null) {
            return path;
        }
        return strMyImagePath;

    }

    // check anh bi quay
    public int getCameraPhotoOrientation(Context context, Uri imageUri, String imagePath){
        int rotate = 0;
        try {
            context.getContentResolver().notifyChange(imageUri, null);
            File imageFile = new File(imagePath);

            ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

            switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_270:
                rotate = 270;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                rotate = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                rotate = 90;
                break;
            }

//            Log.i("RotateImage", "Exif orientation: " + orientation);
//            Log.i("RotateImage", "Rotate value: " + rotate);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rotate;
    }

}

It work for me. I hope it can hepl you!

Radiate answered 4/10, 2017 at 8:39 Comment(0)
C
0

Try this Method,this will convert your Image file to compressed format,and you can customized the compress level by varrying the value of x & y in the code(Indicated in comment line)

      File mImageFile = saveBitmapToFile(ImageFile);

      public File saveBitmapToFile(File file){

      try {

        // BitmapFactory options to downsize the image
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        o.inSampleSize = 6;
        // factor of downsizing the image

        FileInputStream inputStream = new FileInputStream(file);
        //Bitmap selectedBitmap = null;
        BitmapFactory.decodeStream(inputStream, null, o);
        inputStream.close();

        // The new size we want to scale to
        final int REQUIRED_SIZE=200;        // x............

        // Find the correct scale value. It should be the power of 2.
        int scale = 1;
        while(o.outWidth / scale / 2 >= REQUIRED_SIZE &&
                o.outHeight / scale / 2 >= REQUIRED_SIZE) {
            scale *= 2;
        }

        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        inputStream = new FileInputStream(file);

        Bitmap selectedBitmap = BitmapFactory.decodeStream(inputStream, null, o2);
        inputStream.close();

        // here i override the original image file
        File outPutFile = File.createTempFile("abc","image");
        FileOutputStream outputStream = new FileOutputStream(outPutFile);
                                                  // y.......
        selectedBitmap.compress(Bitmap.CompressFormat.JPEG, 95 , outputStream);

        return outPutFile;
    } catch (Exception e) {
        return null;
    }
}

Thanks

Configurationism answered 23/7, 2018 at 13:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.