图片压缩与二次采样
为什么要压缩图片?
可以试想:当一个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的一项重要优化吧!
转载请注明出处