Android图片实现压缩处理的实例代码
时间:2022-07-27
本文章向大家介绍Android图片实现压缩处理的实例代码,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
整理文档,搜刮出一个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
以上就是本文的全部内容,希望对大家的学习有所帮助。
- Java 8 Stream 教程 (一)
- Python文档精要研读系列(1):map函数
- SparkML模型选择(超参数调整)与调优
- visual studio 2012 的制作ActiveX、打包和发布
- 用java提交一个Spark应用程序
- 一步步教你利用Github开源项目实现网络爬虫:以抓取证券日报新闻为例
- 用linqPad帮助你快速学习LINQ
- Java 8 Stream 教程 (二)
- CountVectorizer
- Caliburn.Micro学习笔记(五)----协同IResult
- 一个Pythoner的自我修养系列(一)
- 众里寻她千百度,蓦然回首,那bug却在灯火阑珊处
- Github|Python开源项目漫游指南(一)
- Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释