- 前言
图片压缩与二次采样
为什么要压缩图片?
可以试想:当一个App调用系统的相机进行拍照操作时,如果我们从Intent中获取的data数据设置给图片时,它仅仅显示的是一张略缩图(120x160 宽高),并不能满足我们的需求!于是我们在startActivity()的时候putExtra()指定一个存储路径,获取Uri指定路径下的图片, 在config为ARGB_8888的情况下,每个像素要占用四个字节,一张图片通常会达到3xxx x 4xxx 这样一个级别,计算出来之后 会达到一个几十M的级别 60M,因为默认情况下系统中的每个App只享有16m的独立内存,这样很容易把内存加爆了,所以压缩图片十分重要!
图片压缩的流程
核心
我们加载的时候使用带options参数的方法去加载
- 在options中我们指定inJustDecodeBounds为true,仅解码边缘,这样图片不会真正的被加载到内存中,图片的基本信息,比如宽,高会被加载到内存中
- 压缩比例,采样比例值是2的n次幂,向下取整
- 根据我们想要的宽高和图片的宽高计算一个压缩比例,设置到options上
- 关闭仅解码边缘,重新进行解码
获取指定路径的原图
启动相机的时候传值
private void takePicSave() {
Intent intent = new Intent();
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
//保存 EXTRA_OUTPUT:将拍摄的图片保存到指定uri路径
mUri = getUri();
intent.putExtra(MediaStore.EXTRA_OUTPUT, mUri);
this.startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE_SAVE);
获取指定路径的文件
private Uri getUri() {
if(ActivityCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)==PackageManager.PERMISSION_GRANTED){
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//DCIM
File root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
long time = System.currentTimeMillis();
File picFile = new File(root,time+".jpg");
return Uri.fromFile(picFile);
}else {
File root = this.getCacheDir();
long time = System.currentTimeMillis();
return Uri.parse("file://"+root.getAbsolutePath()+File.separator+time+".jpg");
}
}else {
//申请读写内存卡权限
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_CODE_EXTERNAL);
}
return null;
}
图片的压缩与二次采样
public Bitmap sampleImage(String filePath){
BitmapFactory.Options options = new BitmapFactory.Options();
// 设置仅解码边缘,图片不会真正加载到内存中,解码器加载返回null,
// 但是图片的输出字段会进行赋值
// 比如说 图片的宽,高
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
int outHeight = options.outHeight;
int outWidth = options.outWidth;
int scale = Math.max(outHeight / 300, outWidth / 300);
//scale向下取整,真实取值 2的n次幂
options.inSampleSize = scale;
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filePath,options);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CODE_TAKE_PICTURE_SAVE:
//如果拍照并保存 拍照App传递过来的Intent data空的,没有数据
//图片进行显示
//进行二次采样
Bitmap bitmap = sampleImage(mUri.getPath());
showImage.setImageBitmap(bitmap);
break;
}
这样就实现了图片二次采样压缩,可以自己拿内存工具测测,不压缩之前大概为60M左右,压缩之后为4M左右,大大的降低了内存的占用,也是App的一项重要优化吧!
转载请注明出处