Android图片实现压缩处理的实例代码

作者:MrZang 时间:2022-05-28 20:29:12 

整理文档,搜刮出一个Android图片实现压缩处理的实例代码,稍微整理精简一下做下分享。

详解:

1.获取本地图片File文件 获取BitmapFactory.Options对象 计算原始图片 目标图片宽高比 计算输出的图片宽高

2.根据宽高比计算options.inSampleSize值(缩放比例 If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory.)得到bitmap位图 根据位图对象获取新的输出位图对象 Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)Creates a new bitmap, scaled from an existing bitmap, whenpossible.

3.获取图片方向调整、失量压缩图片保持在1024kb以下


//进行大小缩放来达到压缩的目的
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(srcImagePath, options);
//根据原始图片的宽高比和期望的输出图片的宽高比计算最终输出的图片的宽和高

float srcWidth = options.outWidth;
float srcHeight = options.outHeight;
float maxWidth = outWidth;
float maxHeight = outHeight;
float srcRatio = srcWidth / srcHeight; //原始图片宽高比
float outRatio = maxWidth / maxHeight; //目标图片宽高比
float actualOutWidth = srcWidth;
float actualOutHeight = srcHeight;
 if (srcWidth > maxWidth || srcHeight > maxHeight) {
  if(srcRatio>outRatio){ //原始宽高比大于目标宽高比
    actualOutWidth = maxWidth;
    actualOutHeight = actualOutWidth / srcRatio;
  }else if(srcRatio<outRatio){ //原始宽高比小于目标宽高比
    actualOutHeight = maxHeight;
    actualOutWidth = actualOutHeight * srcRatio;
  }
}else{
  actualOutWidth = maxWidth;
  actualOutHeight = maxHeight;
}

options.inSampleSize = computSampleSize(options, actualOutWidth, actualOutHeight);
options.inJustDecodeBounds = false;
Bitmap scaledBitmap = null;
try {
  scaledBitmap = BitmapFactory.decodeFile(srcImagePath, options);
} catch (OutOfMemoryError e) {
  e.printStackTrace();
}
if (scaledBitmap == null) {
  return null;
}

//生成最终输出的bitmap
Bitmap actualOutBitmap = Bitmap.createScaledBitmap(scaledBitmap, (int) actualOutWidth, (int) actualOutHeight, true);

//释放原始位图资源
if(scaledBitmap!=actualOutBitmap){ //判断目标位图是否和原始位图指向栈目标相同
  scaledBitmap.recycle();
  scaledBitmap = null;
}

//处理图片旋转问题
ExifInterface exif = null;
try {
  exif = new ExifInterface(srcImagePath);
  int orientation = exif.getAttributeInt(
      ExifInterface.TAG_ORIENTATION, 0);
  Matrix matrix = new Matrix();
  if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
    matrix.postRotate(90);
  } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
    matrix.postRotate(180);
  } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
    matrix.postRotate(270);
  }
  actualOutBitmap = Bitmap.createBitmap(actualOutBitmap, 0, 0,
      actualOutBitmap.getWidth(), actualOutBitmap.getHeight(), matrix, true);
} catch (IOException e) {
  e.printStackTrace();
  return null;
}

//进行有损压缩
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int options_ = 100;
actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);//质量压缩方法,把压缩后的数据存放到baos中 (100表示不压缩,0表示压缩到最小)

int baosLength = baos.toByteArray().length;

while (baosLength / 1024 > maxFileSize) {//循环判断如果压缩后图片是否大于maxMemmorrySize,大于继续压缩
  baos.reset();//重置baos即让下一次的写入覆盖之前的内容
  options_ = Math.max(0, options_ - 10);//图片质量每次减少10
  actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);//将压缩后的图片保存到baos中
  baosLength = baos.toByteArray().length;
  if (options_ == 0)//如果图片的质量已降到最低则,不再进行压缩
    break;
}
actualOutBitmap.recycle();

//将bitmap保存到指定路径
FileOutputStream fos = null;
String filePath = getOutputFileName(srcImagePath);
try {
  fos = new FileOutputStream(filePath);
  //包装缓冲流,提高写入速度
  BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fos);
  bufferedOutputStream.write(baos.toByteArray());
  bufferedOutputStream.flush();
} catch (FileNotFoundException e) {
  return null;
} catch (IOException e) {
  return null;
} finally {
  if (baos != null) {
    try {
      baos.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  if (fos != null) {
    try {
      fos.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

//获取位图缩放比例
private int computSampleSize(BitmapFactory.Options options, float reqWidth, float reqHeight) {
  float srcWidth = options.outWidth;//20
  float srcHeight = options.outHeight;//10
  int sampleSize = 1;
  if (srcWidth > reqWidth || srcHeight > reqHeight) {
    int withRatio = Math.round(srcWidth / reqWidth);
    int heightRatio = Math.round(srcHeight / reqHeight);
    sampleSize = Math.min(withRatio, heightRatio);
  }
  return sampleSize;
}

压缩比例换算:


float srcWidth = options.outWidth;
float srcHeight = options.outHeight;
float widthScale = outWidth / srcWidth;//目标/原始 宽比例
float heightScale = outHeight / srcHeight; //目标原始 高比
//对比宽高比选择较大的一种比例
float scale = widthScale > heightScale ? widthScale : heightScale;
float actualOutWidth = srcWidth;
float actualOutHeight = srcHeight;
if (scale < 1) {
 actualOutWidth = srcWidth * scale;
 actualOutHeight = srcHeight * scale;
}

设置缩放比例--生成新的位图


 Matrix matrix1 = new Matrix();
 matrix1.postScale(scale, scale);// 放大缩小比例
 //生成最终输出的bitmap
 Bitmap actualOutBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix1, true);

if (actualOutBitmap != scaledBitmap) {
   scaledBitmap.recycle();
   scaledBitmap = null;
   System.gc();
 }

参考:https://github.com/guizhigang/LGImageCompressor

来源:http://www.jianshu.com/p/b468d2a01065?utm_source=tuicool&utm_medium=referral

标签:Android,图片,压缩
0
投稿

猜你喜欢

  • Java利用Strategy模式实现堆排序

    2022-07-16 08:01:04
  • C#实现支付宝沙箱支付的项目实践

    2021-07-29 17:18:18
  • Java设计模式之Strategy模式

    2023-11-21 03:58:22
  • 如何使用ByteArrayOutputStream下载文件

    2021-07-29 11:32:45
  • Java轻松掌握面向对象的三大特性封装与继承和多态

    2021-07-27 02:39:11
  • Android 开发中layout下的子文件夹

    2021-10-03 16:10:44
  • c# webapi 配置swagger的方法

    2022-03-21 23:38:19
  • Java基础之练习打印三角形

    2023-08-25 05:39:33
  • C#使用SharpZipLib压缩解压文件

    2021-10-27 18:56:21
  • 解决@RequestBody部分属性丢失的问题

    2023-08-01 15:00:21
  • Matlab实现获取文件夹下所有指定后缀的文件

    2021-06-17 23:57:49
  • IDEA2020如何打开Run Dashboard的方法步骤

    2023-02-10 15:29:10
  • JPA Specification常用查询+排序实例

    2023-11-23 04:56:32
  • SpringMVC 上传文件 MultipartFile 转为 File的方法

    2021-07-06 00:28:12
  • MyBatis中使用$和#所遇到的问题及解决办法

    2023-03-25 12:27:55
  • java字符串格式化输出实例讲解

    2022-09-12 10:25:24
  • Spring Cloud Hystrix异常处理方法详解

    2022-05-29 06:20:12
  • struts2如何使用拦截器进行用户权限控制实例

    2023-02-23 18:14:15
  • MyBatis在注解上使用动态SQL方式(@select使用if)

    2023-09-24 06:52:55
  • Maven项目修改JDK版本全过程

    2021-07-19 12:13:29
  • asp之家 软件编程 m.aspxhome.com