简体   繁体   中英

How to change the size of the image without changing resoultion?

I am developing an app in which i want to reduce the size of my image.For example if size is 1MB then i want it to get reduce into kb.

But resolution should not get changed.

Can anyone help in this?

I tried this code but its not working

 public static Bitmap resizeBitMapImage1(String filePath, int targetWidth, int targetHeight) {
 Bitmap bitMapImage = null;
 try {
     Options options = new Options();
     options.inJustDecodeBounds = true;
     BitmapFactory.decodeFile(filePath, options);
     double sampleSize = 0;
     Boolean scaleByHeight = Math.abs(options.outHeight - targetHeight) >= Math.abs(options.outWidth
             - targetWidth);
     if (options.outHeight * options.outWidth * 2 >= 1638) {
         sampleSize = scaleByHeight ? options.outHeight / targetHeight : options.outWidth / targetWidth;
         sampleSize = (int) Math.pow(2d, Math.floor(Math.log(sampleSize) / Math.log(2d)));
     }
     options.inJustDecodeBounds = false;
     options.inTempStorage = new byte[128];
     while (true) {
         try {
             options.inSampleSize = (int) sampleSize;
             bitMapImage = BitmapFactory.decodeFile(filePath, options);
             break;
         } catch (Exception ex) {
             try {
                 sampleSize = sampleSize * 2;
             } catch (Exception ex1) {

             }
         }
     }
 } catch (Exception ex) {

 }
 return bitMapImage;

}

Using this code it reduces the resolution but not much size of the image.

I also tried

public static Bitmap reduceImgSizeToHundredKB(Bitmap bitmap) {
Bitmap scaled = bitmap;
try {
 ByteArrayOutputStream stream = new ByteArrayOutputStream();
  bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);

 } catch (Exception e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
  return null;
 }
   return scaled;

}

If you don't want to resize your image then your only option is to compress it.

Here is an example on how to do that:

byte[] data = null;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bi.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    data = baos.toByteArray();

In my thought, In most cases, we can't do that. Because it related to resolution of the image and the color range of the image.

so, If we have a large image with a lot of colors, then reduce the size of the image will induce to reduce resolution of it.

There are two aproches: lossy (where you'll lose quality of the image) and lossless .

The answer provided by rickman is lossy so it will work well but reduce the quality of the image - it works particularly well for pictures taken with a camera.

The lossless approach is using PNG, which consists of using Bitmap.CompressFormat.PNG as argument to the compress method.

A not as well known but very efficient format is WebP . It's also available as an argument to the compress method ( Bitmap.CompressFormat.PNG ). I'd suggest testing with WebP, specially considering it supports both lossy and lossless compression.

Use this method if you are decoding from path

 public Bitmap decodeSampledBitmapFromPath(String path, int reqWidth,
    int reqHeight) {

final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);

options.inSampleSize = calculateInSampleSize(options, reqWidth,
        reqHeight);

// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmap bmp = BitmapFactory.decodeFile(path, options);
return bmp;
}
}
  public 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) {
    if (width > height) {
        inSampleSize = Math.round((float) height / (float) reqHeight);
    } else {
        inSampleSize = Math.round((float) width / (float) reqWidth);
     }
 }
 return inSampleSize;
}

Use this if you are decoding from resources

    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
    int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

     // Decode bitmap with inSampleSize set
     options.inJustDecodeBounds = false;
     return BitmapFactory.decodeResource(res, resId, options);
    }

public static 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) {

// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) height / (float) reqHeight);
    final int widthRatio = Math.round((float) width / (float) reqWidth);

// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
 }

 return inSampleSize;
}

If you want to reduce the file size of the image without losing a great ammount of quality you can do this: First you need to flatten the image, then save it for web (ctrl+alt+shift+s) Then select the preset PNG-8 128 Dithered. You can now customize this preset by setting the colors to "256", then select "selective" under the PNG-8, under "selective" change dither to "diffusion", deselect the "interlaced" option and make shure that the web snap option is set to 0%.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM