1.需求
业务要求对png, jpg, jpeg, webp 格式图片进行等比例压缩
2.开发中遇到的问题
使用 thumbnails 包, 发现只能压缩 jpg 和 jpeg , 不能压缩webp
接着找到了 webp-imageio 解决webp , 又发现 这俩都不支持 png ,
接着找到了 openviewerfx 去处理png…
3. 实现代码
3.1 pom 引用
<!--压缩png-->
<dependency>
<groupid>org.jpedal</groupid>
<artifactid>openviewerfx</artifactid>
<version>6.6.14</version>
</dependency>
<!-- thumbnailator: 图片缩放和压缩工具 -->
<dependency>
<groupid>net.coobird</groupid>
<artifactid>thumbnailator</artifactid>
<version>0.4.14</version>
</dependency>
<!-- twelvemonkeys: 支持更多图片格式 -->
<dependency>
<groupid>com.twelvemonkeys.imageio</groupid>
<artifactid>imageio-core</artifactid>
<version>3.9.4</version>
</dependency>
<dependency>
<groupid>com.twelvemonkeys.imageio</groupid>
<artifactid>imageio-jpeg</artifactid>
<version>3.9.4</version>
</dependency>
<dependency>
<groupid>com.twelvemonkeys.imageio</groupid>
<artifactid>imageio-webp</artifactid>
<version>3.9.4</version>
</dependency>
<!--压缩webp-->
<dependency>
<groupid>org.apache.commons</groupid>
<artifactid>commons-imaging</artifactid>
<version>1.0-alpha1</version>
</dependency>
<dependency>
<groupid>org.sejda.imageio</groupid>
<artifactid>webp-imageio</artifactid>
<version>0.1.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.imgscalr/imgscalr-lib -->
<dependency>
<groupid>org.imgscalr</groupid>
<artifactid>imgscalr-lib</artifactid>
<version>4.2</version>
</dependency>
3.2 controller 代码
我这里自己定死了生产图片文件夹的路径 , 各位大神按照自己实际的需求改动
package com.example.controller;
import com.example.service.imagecompressionservice;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.web.bind.annotation.postmapping;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.requestparam;
import org.springframework.web.bind.annotation.restcontroller;
import org.springframework.web.multipart.multipartfile;
import javax.imageio.imageio;
import javax.imageio.imagereader;
import java.io.file;
import java.io.ioexception;
import java.util.iterator;
/**
* @classname: imagecompressioncontroller
* @description: todo
* @author: 赵狗
* @date: 2024/8/23 15:04
*/
@requestmapping("/imageapi")
@restcontroller
public class imagecompressioncontroller {
@autowired
private imagecompressionservice imagecompressionservice;
/**
* 图片压缩方法
* @param file
* @param quality
* @return
* @throws ioexception
*/
@postmapping("/compressbysize")
public string compressimagebysize(@requestparam("file") multipartfile file,
@requestparam("quality") string quality
) throws ioexception {
string outputpath = "f:\\images\\" + "compressed_size_" + file.getoriginalfilename();
file outputfile = new file(outputpath);
prepareoutputdirectory(outputfile);
file inputfile = convertmultipartfiletofile(file);
// 将quality转为 float
float qualityfloat = float.parsefloat(quality);
imagecompressionservice.compressimagebysize(inputfile, outputfile,qualityfloat);
inputfile.delete();
return "file compressed successfully by size: " + outputfile.getabsolutepath();
}
/**
* 判断文件夹是否存在, 如果没有则创建
* @param outputfile
*/
private void prepareoutputdirectory(file outputfile) {
if (!outputfile.getparentfile().exists()) {
outputfile.getparentfile().mkdirs();
}
}
/**
* 将multipartfile转换为file
* @param file
* @return
* @throws ioexception
*/
private file convertmultipartfiletofile(multipartfile file) throws ioexception {
file convfile = new file(system.getproperty("java.io.tmpdir") + "/" + file.getoriginalfilename());
file.transferto(convfile);
return convfile;
}
public boolean iswebpsupported() {
iterator<imagereader> readers = imageio.getimagereadersbyformatname("webp");
return readers.hasnext();
}
}
3.3 service 代码
package com.example.service;
import com.idrsolutions.image.png.pngcompressor;
import com.luciad.imageio.webp.webpwriteparam;
import net.coobird.thumbnailator.thumbnails;
import org.springframework.stereotype.service;
import javax.imageio.iioimage;
import javax.imageio.imageio;
import javax.imageio.imagewriteparam;
import javax.imageio.imagewriter;
import javax.imageio.stream.imageoutputstream;
import java.awt.image.bufferedimage;
import java.io.file;
import java.io.ioexception;
import java.util.iterator;
/**
* @classname: imagecompressionservice
* @description: todo
* @author: 赵狗
* @date: 2024/8/23 15:03
*/
@service
public class imagecompressionservice {
private static final int default_quality = 80; // 默认压缩质量为 80
/**
* 压缩图片方法
* @param inputfile
* @param outputfile
* @param quality
* @throws ioexception
*/
public void compressimagebysize(file inputfile, file outputfile, float quality) throws ioexception {
// 根据输入文件的后缀名获取文件格式
string formatname = getfileextension(inputfile);
// 根据不同的文件格式,调用相应的压缩方法
if ("webp".equalsignorecase(formatname)) {
// 对webp格式的图片进行压缩
compresswebpimage(inputfile,outputfile,quality);
} else if("png".equalsignorecase(formatname)){
// 对png格式的图片进行压缩
compresspngimage(inputfile, outputfile);
} else {
// 对jpg或其他格式的图片进行压缩,这里假设jpg的压缩方法与其他格式不同
compressjpgimage(inputfile, outputfile, quality, formatname);
}
}
/**
* 压缩jpg 以及 jpeg 格式的图片方法
* @param inputfile
* @param outputfile
* @param quality
* @param formatname
* @throws ioexception
*/
private void compressjpgimage(file inputfile, file outputfile, float quality, string formatname) throws ioexception {
// 压缩jpg 以及 jpeg 格式的图片
thumbnails.of(inputfile)
.scale(1) // 明确告诉库不需要改变图片尺寸
.outputquality(quality) // 设置输出图片的质量
.outputformat(formatname) // 保持原有格式
.tofile(outputfile);
}
/**
* 压缩png格式图片方法
* @param inputfile
* @param outputfile
* @throws ioexception
*/
private void compresspngimage(file inputfile, file outputfile) throws ioexception {
pngcompressor.compress(inputfile, outputfile);
}
/**
* 压缩webp格式图片方法
* @param inputfile
* @param outputfile
* @param quality
* @throws ioexception
*/
public void compresswebpimage(file inputfile, file outputfile, float quality) throws ioexception {
// 读取输入的webp图像
bufferedimage image = imageio.read(inputfile);
// 获取webp格式的imagewriter
iterator<imagewriter> writers = imageio.getimagewritersbyformatname("webp");
if (!writers.hasnext()) {
throw new illegalstateexception("no webp writer found");
}
imagewriter writer = writers.next();
// 设置输出流
try (imageoutputstream ios = imageio.createimageoutputstream(outputfile)) {
writer.setoutput(ios);
// 设置压缩参数
webpwriteparam writeparam = (webpwriteparam) writer.getdefaultwriteparam();
writeparam.setcompressionmode(imagewriteparam.mode_explicit);
writeparam.setcompressiontype("lossy");
writeparam.setcompressionquality(quality); // 设置压缩质量,值范围 0.0 ~ 1.0
// 写出压缩后的webp图像
writer.write(null, new iioimage(image, null, null), writeparam);
} finally {
writer.dispose();
}
}
/**
* 获取图片类型方法
* @param file
* @return
*/
private string getfileextension(file file) {
string name = file.getname();
return name.substring(name.lastindexof('.') + 1).tolowercase();
}
}
3.4 apifox 调用

3.5 效果图
3.5.1 压缩前:




3.5.2 压缩后



以上就是springboot压缩png, jpg, jpeg, webp类型图片的实现代码的详细内容,更多关于springboot压缩图片的资料请关注代码网其它相关文章!
发表评论