使用谷歌压缩工具Thumbnailator, 支持 图片缩放,区域裁剪,水印,旋转等,自行研究
net.coobird
thumbnailator
0.4.8
保持图片尺寸不变,压缩大小,代码如下:
import net.coobird.thumbnailator.Thumbnails;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* 图片压缩
* @author
*/
@Slf4j
public class ImageCompressUtil {
/**
* 图片质量压缩,不改变大小
* @param file
* @param destPath
* @param quality
* @return
* @throws IOException
*/
public static String compressImage(File file, String destPath, float quality) {
try {
if (!file.exists()) {
log.error("compressImage file not found 文件不存在");
throw new FileNotFoundException("文件不存在");
}
File destFile = new File(destPath);
if (!destFile.exists() && destFile.isDirectory()) {
destFile.mkdirs();
}
String destFileUrl = destPath + File.separator + file.getName();
Thumbnails.of(file)
.scale(1f)
.outputQuality(quality)
.toFile(destFileUrl);
return destFileUrl;
} catch (IOException e) {
log.error("e");
return "";
}
}
/**
* 压缩图片
* @param httpUrl 图片地址
* @param destPath
* @return
*/
public static String compressHttpUrl(String httpUrl, String destPath) {
try {
URL url = new URL(httpUrl);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
InputStream input = connection.getInputStream();
String destUrl = destPath + httpUrl.substring(httpUrl.lastIndexOf('/'));
Thumbnails.of(input)
.scale(1f)
// .size(200, 500) 大小
// .outputQuality(0.5f) 质量
// .outputFormat("jpg") 图片格式
// .useOriginalFormat() 使用原文件格式
.toFile(destUrl);
input.close();
return destUrl;
} catch (IOException e) {
log.error("压缩图片异常");
return "";
}
}
public static void main(String[] args) {
// String url = "";
// String destPath = "C:/test/image";
// compressImage(new File(url), destPath, 0.25f);
// compressHttpUrl(url, destPath);
}
}
利用上面的代码进行图片压缩时,非jpeg格式的图片会出现 Unsupported Image Type
在不改变代码基础可以借助第三方包解决:
引入twelvemonkeys 自动发现
com.twelvemonkeys.imageio
imageio-jpeg
3.4.1
第二种方式,利用ImageIO和twelvemonkeys 进行压缩
/**
* 图片质量压缩,大小不变
* @param url
* @param destFilePath
* @param quality 0-1
* @return
*/
public static String compressImageQuality(String url, String destFilePath, float quality) {
log.info("compressPictureByQuality 图片压缩|url:" + url + ";destFilePath:" + destFilePath
+ ";quality:" + quality);
String destFileUrl = destFilePath + url.substring(url.lastIndexOf("/"));
File destFileDir = new File(destFilePath);
if (!destFileDir.exists()) {
destFileDir.mkdirs();
}
File destFile = new File(destFileUrl);
try (FileOutputStream out = new FileOutputStream(destFile)) {
File file = new File(url);
if (!file.exists()) {
log.error("Not Found Img File,文件不存在");
throw new FileNotFoundException("Not Found Img File,文件不存在");
}
log.info("图片压缩前大小" + file.length() + "字节");
ImageWriteParam imgWriteParams = new javax.imageio.plugins.jpeg.JPEGImageWriteParam(null);
// 要使用压缩,必须指定压缩方式为MODE_EXPLICIT
imgWriteParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
// 这里指定压缩的程度,参数quality是取值0~1范围内,
imgWriteParams.setCompressionQuality(quality);
imgWriteParams.setProgressiveMode(ImageWriteParam.MODE_DISABLED);
// 使用RGB格式
ColorModel colorModel = ColorModel.getRGBdefault();
// 文件
BufferedImage bufferedImage = ImageIO.read(file);
// 指定压缩时使用的色彩模式
imgWriteParams.setDestinationType(new javax.imageio.ImageTypeSpecifier(colorModel,
colorModel.createCompatibleSampleModel(
bufferedImage.getWidth(), bufferedImage.getHeight())));
// 指定写图片的方式为 jpg
ImageWriter imgWriter = ImageIO.getImageWritersByFormatName("jpg").next();
imgWriter.reset();
// 必须先指定out值,才能调用write方法, ImageOutputStream可以通过任何OutputStream构造
imgWriter.setOutput(ImageIO.createImageOutputStream(out));
// 调用write方法,就可以向输入流写图片
imgWriter.write(null, new IIOImage(bufferedImage, null, null),
imgWriteParams);
log.info("结束设定压缩图片参数");
bufferedImage.flush();
out.flush();
log.info("图片压缩后大小" + destFile.length() + "字节");
return destFileUrl;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
踩坑说明:
DataInputStream dataInputStream;
Thumbnails.of(dataInputStream).size(width, height).keepAspectRatio(false).useOriginalFormat().toFile(destFileUrl);
直接使用Thumbnails.of(dataInputStream) 会出现错误:UnsupportedFormatException: No suitable ImageReader found for source data
解决方法:
1.把input存成本地文件,利用本地文件路径操作 Thumbnails.of(url)
2.转换成BufferedImage
BufferedImage bufferedImage = ImageIO.read(dataInputStream);
Thumbnails.of(bufferedImage ).size(width, height).keepAspectRatio(false).useOriginalFormat().toFile(destFileUrl);
更多压缩方式可以参考:https://blog.csdn.net/zmx729618/article/details/78729049