轉載:java圖片壓縮工具類(指定壓縮大小) - 一個九零後的程序猿 - 博客園 (cnblogs.com)
1:先導入依賴
<!--thumbnailator圖片處理-->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
2:創建工具類--->PicUtils
import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
/**
* @PROJECT_NAME: water_chivalry
* @AUTHOR: Hanson-Hsc
* @DATE: 2020-07-27 09:08
* @DESCRIPTION: 圖片壓縮工具
* @VERSION:
*/
public class PicUtils {
//以下是常量,按照阿里代碼開發規范,不允許代碼中出現魔法值
private static final Logger logger = LoggerFactory.getLogger(PicUtils.class);
private static final Integer ZERO = 0;
private static final Integer ONE_ZERO_TWO_FOUR = 1024;
private static final Integer NINE_ZERO_ZERO = 900;
private static final Integer THREE_TWO_SEVEN_FIVE = 3275;
private static final Integer TWO_ZERO_FOUR_SEVEN = 2047;
private static final Double ZERO_EIGHT_FIVE = 0.85;
private static final Double ZERO_SIX = 0.6;
private static final Double ZERO_FOUR_FOUR = 0.44;
private static final Double ZERO_FOUR = 0.4;
/**
* 根據指定大小壓縮圖片
*
* @param imageBytes 源圖片字節數組
* @param desFileSize 指定圖片大小,單位kb
* @return 壓縮質量后的圖片字節數組
*/
public static byte[] compressPicForScale(byte[] imageBytes, long desFileSize) {
if (imageBytes == null || imageBytes.length <= ZERO || imageBytes.length < desFileSize * ONE_ZERO_TWO_FOUR) {
return imageBytes;
}
long srcSize = imageBytes.length;
double accuracy = getAccuracy(srcSize / ONE_ZERO_TWO_FOUR);
try {
while (imageBytes.length > desFileSize * ONE_ZERO_TWO_FOUR) {
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("圖片原大小={}kb | 壓縮后大小={}kb",
srcSize / ONE_ZERO_TWO_FOUR, imageBytes.length / ONE_ZERO_TWO_FOUR);
} catch (Exception e) {
logger.error("【圖片壓縮】msg=圖片壓縮失敗!", e);
}
return imageBytes;
}
/**
* 自動調節精度(經驗數值)
*
* @param size 源圖片大小
* @return 圖片壓縮質量比
*/
private static double getAccuracy(long size) {
double accuracy;
if (size < NINE_ZERO_ZERO) {
accuracy = ZERO_EIGHT_FIVE;
} else if (size < TWO_ZERO_FOUR_SEVEN) {
accuracy = ZERO_SIX;
} else if (size < THREE_TWO_SEVEN_FIVE) {
accuracy = ZERO_FOUR_FOUR;
} else {
accuracy = ZERO_FOUR;
}
return accuracy;
}
}
3:在上傳圖片接口處進行壓縮
/**
* 圖片上傳(招租廣告圖片專用入口)
*/
@PostMapping("file/img")
@ApiOperation(value = "圖片上傳接口(廣告圖片專用入口)")public ResultVo imgUploads(@RequestParam("file") MultipartFile file) throws IOException {
//壓縮圖片到指定120K以內,不管你的圖片有多少兆,都不會超過120kb,精度還算可以,不會模糊
byte[] bytes = PicUtils.compressPicForScale(file.getBytes(), 120);
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
//生成保存在服務器的圖片名稱,統一修改原后綴名為:jpg
String newFileName = UUID.randomUUID() + ".jpg";
OSSUtil.upload2(newFileName, inputStream);
JSONObject result = new JSONObject();
result.put("url", OSSUtil.getUrl2(newFileName, ""));
return ResultVoUtil.success(result);
}
4.還有一個壓縮圖片工具類,但是不能指定壓縮大小,可是很有用,壓縮不會丟失精度,圖片也很清晰:
import com.bamboo.water_chivalry.common.enums.ResultEnum;
import com.bamboo.water_chivalry.common.exception.GlobalException;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
@PROJECT_NAME: water_chivalry
@AUTHOR: Hanson-Hsc
@DATE: 2020-07-20 09:24
@DESCRIPTION: 圖片壓縮工具
-
@VERSION:
*/
public class ImgCompression {public static InputStream getImageCom(MultipartFile file) throws IOException {
//獲取文件輸入流
InputStream inputStream = file.getInputStream();
try {
// 把圖片讀入到內存中
BufferedImage bufImg = ImageIO.read(inputStream);
// 壓縮代碼,存儲圖片文件byte數組
ByteArrayOutputStream bos = new ByteArrayOutputStream();
//防止圖片變紅,這一步非常重要
BufferedImage bufferedImage = new BufferedImage(bufImg.getWidth(), bufImg.getHeight(), BufferedImage.TYPE_INT_RGB);
bufferedImage.createGraphics().drawImage(bufImg,0,0, Color.WHITE,null);
//先轉成jpg格式來壓縮,然后在通過OSS來修改成源文件本來的后綴格式
ImageIO.write(bufferedImage,"jpg",bos);
//獲取輸出流
inputStream = new ByteArrayInputStream(bos.toByteArray());
return inputStream;
} catch (IOException e) {
e.printStackTrace();
throw new GlobalException(ResultEnum.IMG_UPLOAD_ERROR);
}finally {
inputStream.close();
}
}
}