功能这么齐全的图片压缩类,还有谁?

2023-12-01 03:10
文章标签 功能 图片 压缩 齐全

本文主要是介绍功能这么齐全的图片压缩类,还有谁?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

效果图:

这里写图片描述

压缩日志

com.pengkv.moon I/--->: 原尺寸:1215*1080
com.pengkv.moon I/--->: 最终压缩比例:3倍/新尺寸:405*360

工具特点

 * 可以解析单张图片* 可以解析多张图片* 处理了压缩过程中OOM* 处理了部分手机照片旋转问题* 压缩后存储在缓存中,并可以清理* 压缩后返回缓存路径,方便上传* 可以从缓存路径读取出Bitmap,方便展示* 封装在2个类里,方便调用

使用方法

ImageCompressUtil.compressImageList(this, photos, new ImageCompressUtil.ProcessImgListCallBack() {@Overridepublic void compressSuccess(final List<String> imgList) {//imgList为压缩后图片的路径}
});

压缩工具类

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;import utils.ImageRotateUtil;/*** Created by pengkv on 15/12/2.* 图片压缩工具类*/
public class ImageCompressUtil {private static List<String> mImageList = new ArrayList<>();// 临时图片集合private static String mImagePath = ""; // 单个临时图片public static String cachePath = "";public static int reqWidth = 320;public static int reqHeight = 480;//压缩单张图片方法public static void compressImage(final Context ctx, final String filePath, final ProcessImgCallBack callBack) {mImagePath = "";//清空路径new Thread(new Runnable() {@Overridepublic void run() {//如果路径是图片,则进行压缩if (isImage(filePath)) {mImagePath = compress(ctx, filePath);}callBack.compressSuccess(mImagePath);}}).start();}//压缩图片集合方法public static void compressImageList(final Context ctx, final List<String> fileList, final ProcessImgListCallBack callBack) {mImageList.clear();//清空集合if (fileList == null || fileList.isEmpty()) {callBack.compressSuccess(mImageList);return;}new Thread(new Runnable() {@Overridepublic void run() {String tempPath = "";for (String imagePath : fileList) {if (isImage(imagePath)) {tempPath = compress(ctx, imagePath);mImageList.add(tempPath);}}callBack.compressSuccess(mImageList);}}).start();}//图片压缩的方法public static String compress(Context ctx, String filePath) {if (TextUtils.isEmpty(filePath))return filePath;File file = new File(filePath);if (!file.exists())//判断路径是否存在return filePath;if (file.length() < 1)//文件是否为空return null;File tempFile = getDiskCacheDir(ctx);String outImagePath = tempFile.getAbsolutePath(); // 输出图片文件路径int degree = ImageRotateUtil.getBitmapDegree(filePath); // 检查图片的旋转角度//谷歌官网压缩图片final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeFile(filePath, options);options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);options.inJustDecodeBounds = false;Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);// 旋转:这步处理主要是为了处理三星手机拍的照片if (degree > 0) {bitmap = ImageRotateUtil.rotateBitmapByDegree(bitmap, degree);}// 写入文件FileOutputStream fos;try {fos = new FileOutputStream(tempFile);bitmap.compress(Bitmap.CompressFormat.JPEG, 70, fos);fos.flush();fos.close();bitmap.recycle();} catch (FileNotFoundException e) {e.printStackTrace();return filePath;} catch (Exception e) {e.printStackTrace();return filePath;}return outImagePath;}/*** 计算压缩比例值* 按照2、3、4...倍压缩** @param options   解析图片的配置信息* @param reqWidth  所需图片压缩尺寸最小宽度* @param reqHeight 所需图片压缩尺寸最小高度* @return*/public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {final int picheight = options.outHeight;final int picwidth = options.outWidth;Log.i("--->", "原尺寸:" + picwidth + "*" + picheight);int targetheight = picheight;int targetwidth = picwidth;int inSampleSize = 1;if (targetheight > reqHeight || targetwidth > reqWidth) {while (targetheight >= reqHeight && targetwidth >= reqWidth) {inSampleSize += 1;targetheight = picheight / inSampleSize;targetwidth = picwidth / inSampleSize;}}Log.i("--->", "最终压缩比例:" + inSampleSize + "倍/新尺寸:" + targetwidth + "*" + targetheight);return inSampleSize;}//图片集合压缩成功后的回调接口public interface ProcessImgListCallBack {void compressSuccess(List<String> imgList);}//单张图片压缩成功后的回调接口public interface ProcessImgCallBack {void compressSuccess(String imgPath);}/*** 获取文件后缀名** @param fileName* @return 文件后缀名*/public static String getFileType(String fileName) {if (!TextUtils.isEmpty(fileName)) {int typeIndex = fileName.lastIndexOf(".");if (typeIndex != -1) {String fileType = fileName.substring(typeIndex + 1).toLowerCase();return fileType;}}return "";}/*** 判断是否是图片** @param fileName* @return 是否是图片类型*/public static boolean isImage(String fileName) {String type = getFileType(fileName);if (!TextUtils.isEmpty(type) && (type.equals("jpg") || type.equals("gif")|| type.equals("png") || type.equals("jpeg")|| type.equals("bmp") || type.equals("wbmp")|| type.equals("ico") || type.equals("jpe"))) {return true;}return false;}/*** 将压缩后的图片存储在缓存中*/public static File getDiskCacheDir(Context ctx) {if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())|| !Environment.isExternalStorageRemovable()) {cachePath = ctx.getExternalCacheDir().getPath();} else {cachePath = ctx.getCacheDir().getPath();}String uniqueName = System.currentTimeMillis() + "_tmp.jpg";return new File(cachePath + File.separator + uniqueName);}/*** 清理缓存文件夹*/public static void clearCache(Context ctx) {File file = new File(cachePath);File[] childFile = file.listFiles();if (childFile == null || childFile.length == 0) {return;}for (File f : childFile) {f.delete(); // 循环删除子文件}}/*** 从图片路径读取出图片** @param imagePath* @return*/private Bitmap decodeFile(String imagePath) {Bitmap bitmap = null;try {File file = new File(imagePath);BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = false;FileInputStream fis = new FileInputStream(file);bitmap = BitmapFactory.decodeStream(fis, null, options);fis.close();} catch (IOException e) {e.printStackTrace();}return bitmap;}
}

图片旋转工具类

import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.media.ExifInterface;import java.io.IOException;/*** Created by pengkv on 15/12/2.* 图片旋转工具类*/
public class ImageRotateUtil {/*** 读取图片的旋转的角度** @param path 图片绝对路径* @return 图片的旋转角度*/public static int getBitmapDegree(String path) {int degree = 0;try {// 从指定路径下读取图片,并获取其EXIF信息ExifInterface exifInterface = new ExifInterface(path);// 获取图片的旋转信息int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);switch (orientation) {case ExifInterface.ORIENTATION_ROTATE_90:degree = 90;break;case ExifInterface.ORIENTATION_ROTATE_180:degree = 180;break;case ExifInterface.ORIENTATION_ROTATE_270:degree = 270;break;}} catch (IOException e) {e.printStackTrace();}return degree;}/*** 将图片按照某个角度进行旋转** @param bm     需要旋转的图片* @param degree 旋转角度* @return 旋转后的图片*/public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {Bitmap returnBm = null;// 根据旋转角度,生成旋转矩阵Matrix matrix = new Matrix();matrix.postRotate(degree);try {// 将原始图片按照旋转矩阵进行旋转,并得到新的图片returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);} catch (OutOfMemoryError e) {e.printStackTrace();//当内存溢出时,利用递归进行重新旋转while (returnBm == null) {System.gc();System.runFinalization();returnBm = rotateBitmapByDegree(bm, degree);}}if (returnBm == null) {returnBm = bm;}if (bm != returnBm) {bm.recycle();}return returnBm;}
}

最后小结

可以更改类中的压缩参数,对图片压缩的质量进行调整

这篇关于功能这么齐全的图片压缩类,还有谁?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/439562

相关文章

使用EasyPoi快速导出Word文档功能的实现步骤

《使用EasyPoi快速导出Word文档功能的实现步骤》EasyPoi是一个基于ApachePOI的开源Java工具库,旨在简化Excel和Word文档的操作,本文将详细介绍如何使用EasyPoi快速... 目录一、准备工作1、引入依赖二、准备好一个word模版文件三、编写导出方法的工具类四、在Export

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

C#实现高性能拍照与水印添加功能完整方案

《C#实现高性能拍照与水印添加功能完整方案》在工业检测、质量追溯等应用场景中,经常需要对产品进行拍照并添加相关信息水印,本文将详细介绍如何使用C#实现一个高性能的拍照和水印添加功能,包含完整的代码实现... 目录1. 概述2. 功能架构设计3. 核心代码实现python3.1 主拍照方法3.2 安全HBIT

录音功能在哪里? 电脑手机等设备打开录音功能的技巧

《录音功能在哪里?电脑手机等设备打开录音功能的技巧》很多时候我们需要使用录音功能,电脑和手机这些常用设备怎么使用录音功能呢?下面我们就来看看详细的教程... 我们在会议讨论、采访记录、课堂学习、灵感创作、法律取证、重要对话时,都可能有录音需求,便于留存关键信息。下面分享一下如何在电脑端和手机端上找到录音功能

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

Debian 13升级后网络转发等功能异常怎么办? 并非错误而是管理机制变更

《Debian13升级后网络转发等功能异常怎么办?并非错误而是管理机制变更》很多朋友反馈,更新到Debian13后网络转发等功能异常,这并非BUG而是Debian13Trixie调整... 日前 Debian 13 Trixie 发布后已经有众多网友升级到新版本,只不过升级后发现某些功能存在异常,例如网络转