Java使用Thumbnails实现图片指定大小压缩

您所在的位置:网站首页 图片大小为5m的图片 Java使用Thumbnails实现图片指定大小压缩

Java使用Thumbnails实现图片指定大小压缩

2023-07-25 17:45| 来源: 网络整理| 查看: 265

Java使用Thumbnails实现图片指定大小压缩

项目中有个要求,对上传服务器的图片大小进行判断,大于50k的图片要进行压缩处理,让其小于50k后在上传。针对图片压缩,一般有以下两种方法:1)java api的ImageIO实现图片压缩,但效果不好,图片压缩后出现变红现象,看了网上的博客普遍都说bug比较多,会有OOM内存溢出的现象。2)该方法使用的是谷歌的Thumbnails插件来实现图片压缩。本文主要介绍的是使用插件实现图片压缩。

实现: Thumbnails.of("源文件路径") .scale(1f) //0-1 float 压缩大小 .outputQuality(0.7f) //0-1 压缩质量 .toFile("新文件路径"); 需要引入的依赖: net.coobird thumbnailator 0.4.8 使用Thumbnails插件实现图片压缩方法有以下两种实现方式: 第一种方式,实现思路: 按照一定的比例压缩图片,递归压缩图片,如果压缩后的图片还不满足要求,则继续进行压缩,直到压缩后的图片大小满足要求。 代码实现: public class ThumbnailUtil { /** * 根据指定大小和指定经度压缩图片 * * @param srcPath 源图片地址 * @param desPath 目标图片地址 * @param desFileSize 指定图片大小,单位kb * @param accuracy 精度,递归压缩的比率,建议小于0.9 * @return */ public static String compressPictureForScale(String srcPath, String desPath, long desFileSize, double accuracy) { if (StringUtils.isEmpty(srcPath) || StringUtils.isEmpty(desPath)) { return null; } if (!new File(srcPath).exists()) { return null; } try { File srcFile = new File(srcPath); long srcFileSize = srcFile.length(); System.out.println("源图片: " + srcPath + ", 大小: " + srcFileSize / 1024 + "kb"); //1.先转换成jpg Thumbnails.of(srcPath).scale(1f).toFile(desPath); //递归压缩,直到目标文件大小小于desFileSize compressPicCycle(desPath, desFileSize, accuracy); File desFile = new File(desPath); System.out.println("目标图片: " + desPath + ", 大小: " + desFile.length() / 1024 + "kb"); System.out.println("图片压缩完成!"); } catch (Exception e) { e.printStackTrace(); return null; } return desPath; } private static void compressPicCycle(String desPath, long desFileSize, double accuracy) throws IOException { File srcFileJPG = new File(desPath); long srcFileSizeJPG = srcFileJPG.length(); //2.判断大小,如果小于50kb,不用压缩,如果大于等于50kb,需要压缩 if (srcFileSizeJPG String srcPath = "C:\\Users\\hemanman6\\Desktop\\微信图片_20210802151348.png"; String desPath = "C:\\Users\\hemanman6\\Desktop\\2.jpg"; ThumbnailUtil.compressPictureForScale(srcPath,desPath,50,0.8); } } 结果显示:

在这里插入图片描述 注意:

png转jpg图片占存大小变小,jgp转png图片占存大小变大

为了更贴近公司的业务代码,对上述代码进行改进,去除了一些多余的IO过程,把递归改成了循环,并且把文件操作改为了流和字节数组的操作。

第二种,使用循环方式、流、字节数组实现 代码实现如下: public class ThumbnailUtis1 { private static Logger logger = LoggerFactory.getLogger(ThumbnailUtis1.class); /** * 根据指定大小压缩图片 * * @param imageBytes 源图片字节数组 * @param desFileSize 指定图片大小,单位kb * @param imageId 影像编号 * @return 压缩质量后的图片字节数组 */ public static byte[] compressPictureForScale(byte[] imageBytes, long desFileSize, String imageId) { if (imageBytes == null || imageBytes.length while (imageBytes.length > desFileSize * 1024) { ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length); Thumbnails.of(inputStream).scale(accuracy).outputQuality(accuracy).toOutputStream(outputStream); imageBytes = outputStream.toByteArray(); } logger.info("【图片压缩】imageId={} | 图片原大小={}kb | 压缩后大小={}kb", imageId, srcSize / 1024, imageBytes.length / 1024); } catch (Exception e) { logger.error("【图片压缩】msg=图片压缩失败!", e); } return imageBytes; } /** * 自动调节精度(经验数值) * * @param size 源图片大小 * @return 图片压缩质量比 */ private static double getAccuracy(long size) { double accuracy; if (size accuracy = 0.6; } else if (size accuracy = 0.4; } return accuracy; } public static void main(String[] args) throws IOException { //将文件内容读入字节数组。文件始终处于关闭状态。 byte[] bytes = FileUtils.readFileToByteArray(new File("C:\\Users\\hemanman6\\Desktop\\微信图片_20210802151348.jpg")); long l = System.currentTimeMillis(); bytes = ThumbnailUtis1.compressPictureForScale(bytes,30,"x"); System.out.println(System.currentTimeMillis()-1); //将字节数组写入到文件 FileUtils.writeByteArrayToFile(new File("C:\\Users\\hemanman6\\Desktop\\333.jpg"),bytes); } }

其中,FileUtils类需要引入如下依赖:

commons-io commons-io 2.6 结果显示:

在这里插入图片描述 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3