简体   繁体   English

如何更改图像大小而又不改变边框大小?

[英]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. 我正在开发一个想要缩小图像大小的应用程序,例如,如果大小为1MB,则希望将其缩小为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. rickman提供的答案是有损的,因此可以很好地工作,但会降低图像质量-对于使用相机拍摄的照片,效果特别好。

The lossless approach is using PNG, which consists of using Bitmap.CompressFormat.PNG as argument to the compress method. 无损方法使用的是PNG,该方法包括使用Bitmap.CompressFormat.PNG作为compress方法的参数。

A not as well known but very efficient format is WebP . WebP是一种不太知名但非常有效的格式。 It's also available as an argument to the compress method ( Bitmap.CompressFormat.PNG ). 它也可以作为compress方法( Bitmap.CompressFormat.PNG )的参数。 I'd suggest testing with WebP, specially considering it supports both lossy and lossless compression. 我建议使用WebP进行测试,特别是考虑到它支持有损和无损压缩。

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. 如果要减小图像的文件大小而不损失大量质量,则可以执行以下操作:首先需要将图像展平,然后将其保存为Web(ctrl + alt + shift + s),然后选择预设的PNG -8128抖动。 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%. 现在,您可以通过以下方式自定义此预设:将颜色设置为“ 256”,然后在PNG-8下选择“选择”,在“选择”下将抖动更改为“扩散”,取消选择“隔行扫描”选项,并确保网络捕捉选项设置为0%。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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