现在手机中相机的像素越来越高因,手机照的相片就越来越来大, 我们想通过选择相册中图片来显示在界面中,或者进行分享. 因为图片太大的原因很容易造成手机出现OMM而崩溃,一些分享照片的平台对分享图片的大小也有一定的限制.所以我们就必须对从相册选出来的图片进行压缩.

选取图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* 打开系统相册
*/
public void openAlbum(){
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
//设置请求码,以便我们区分返回的数据
startActivityForResult(intent, 100);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (100 == requestCode) {
if (data != null) {
//获取数据、获取内容解析者对象
try {
Bitmap mBitmap = BitmapFactory.decodeStream(
getContentResolver().openInputStream(data.getData()));
imageview.setImageBitmap(mBitmap);

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

压缩打开的图片

下面看具体代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* 计算位图的采样比例大小
* @param options
* @param imageView 控件(根据控件的大小进行压缩)
* @return
*/
private static int calculatInSampleSize(BitmapFactory.Options options, ImageView imageView) {
//获取位图的原宽高
final int w = options.outWidth;
final int h = options.outHeight;

if (imageView!=null){
//获取控件的宽高
final int reqWidth = imageView.getWidth();
final int reqHeight = imageView.getHeight();

//默认为一(就是不压缩)
int inSampleSize = 1;
//如果原图的宽高比需要的图片宽高大
if (w > reqWidth || h > reqHeight) {
if (w > h) {
inSampleSize = Math.round((float) h / (float) reqHeight);
} else {
inSampleSize = Math.round((float) w / (float) reqWidth);
}
}

System.out.println("压缩比为:" + inSampleSize);

return inSampleSize;

}else {
return 1;
}
}

这里是对图像压缩比的计算,因为我项目的原因,所以我的压缩比计算是通过传入的ImageView的宽高来计算的,如果想根据自己设置的宽高来压缩只要把,传入的参数:ImageView imageView,改成int width,int height

然后再修改方法中相应的代码即可! 这个方法在很多博客中也提到过…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* 将Uri转换成Bitmap
* @param context
* @param uri
* @param options
* @return
*/
public static Bitmap decodeBitmap(Context context, Uri uri, BitmapFactory.Options options) {
Bitmap bitmap = null;

if (uri != null) {
ContentResolver cr = context.getContentResolver();
InputStream inputStream = null;
try {
/**
* 将图片的Uri地址转换成一个输入流
*/
inputStream = cr.openInputStream(uri);

/**
* 将输入流转换成Bitmap
*/
bitmap = BitmapFactory.decodeStream(inputStream, null, options);

assert inputStream != null;
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return bitmap;
}

这个方法是将将Uri地址转换成一个Bitmap. 因为我们从相册选择图片后会在 OnActivityResult返回一个Intent对象data,我们通过这个 data的getdata()方法就可以得到一个Uri 地址…

然后就是最后一个方法了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 对图片进行重新采样
* @param context
* @param uri 图片的Uri地址
* @param imageView
* @return
*/
public static Bitmap compressBitmap(Context context, Uri uri, ImageView imageView) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
decodeBitmap(context, uri, options);
options = new BitmapFactory.Options();
options.inSampleSize = calculatInSampleSize(options, imageView);
Bitmap bitmap = null;

try {
bitmap = decodeBitmap(context, uri, options);
} catch (Exception e) {
e.printStackTrace();
}

return bitmap;
}

这个方法是将得到Bitmap 通过计算出来的压缩比 进行重新采样返回一个压缩后的Bitmap对象!,也是我们最终调用的方法,方法简单不必多说!

具体使用:
把上面的代码写在一个工具类中,然后在需要使用的地方调用 compressBitmap()即可!

1
2
3
4
5
6
7
8
9
10
11
if (requestCode == GALLERY_REQUEST_CODE) {//是否是从图库返回
try {
Uri originalUri = data.getData(); // 获得图片的uri
//对图片进行压缩
Bitmap bitmap = BitmapCompress.compressBitmap(getActivity(),originalUri,ivpapers);
ivpapers.setImageBitmap(bitmap);
System.out.println("压缩后图片的高度:"+bitmap.getHeight());
System.out.println("压缩后图片的宽度:"+bitmap.getWidth());
} catch (Exception e) {
e.printStackTrace();
}

博参考:https://blog.csdn.net/qq_23179075/article/details/52261588