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
投稿

猜你喜欢

  • spring web.xml指定配置文件过程解析

    2023-05-15 01:32:40
  • Springboot实现多服务器session共享

    2022-09-06 13:58:34
  • Android实现支付宝支付密码输入界面

    2023-06-20 14:57:15
  • java去除字符串中的空格、回车、换行符、制表符的小例子

    2022-04-13 12:33:44
  • 总结Java对象被序列化的两种方法

    2023-05-11 09:46:52
  • Java线程的生命周期的详解

    2022-05-18 00:32:08
  • Android 数据存储方式有哪几种

    2023-12-10 17:20:16
  • android BitmapFactory.Options使用方法详解

    2023-05-04 08:50:20
  • 详解android使用ItemDecoration 悬浮导航栏效果

    2022-05-07 18:17:09
  • mybatisplus使用xml的示例详解

    2021-08-21 18:19:27
  • Android中自定义标题栏样式的两种方法

    2022-05-03 09:06:01
  • Android编程动态按钮实现方法

    2021-12-31 18:05:17
  • Spring JPA find分页示例详解

    2023-05-09 00:36:46
  • 基于Spring Boot应用ApplicationEvent案例场景

    2023-08-17 22:38:12
  • Android ViewPager实现Banner循环播放

    2022-07-16 06:24:03
  • 快速理解Java垃圾回收和jvm中的stw

    2021-09-06 20:27:17
  • java 深拷贝与浅拷贝机制详解

    2023-02-18 19:00:59
  • springmvc与mybatis集成配置实例详解

    2021-06-16 22:10:27
  • SpringCloud实战小贴士之Zuul的路径匹配

    2021-05-26 13:26:36
  • Java中的InputStreamReader和OutputStreamWriter源码分析_动力节点Java学院整理

    2022-10-13 10:46:53
  • asp之家 软件编程 m.aspxhome.com