package org.sxkj.resource.util;
|
|
import lombok.extern.slf4j.Slf4j;
|
import net.coobird.thumbnailator.Thumbnails;
|
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
import javax.imageio.ImageIO;
|
import javax.imageio.ImageReader;
|
import javax.imageio.stream.ImageInputStream;
|
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayOutputStream;
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.util.Date;
|
import java.util.HashMap;
|
import java.util.Iterator;
|
import java.util.Map;
|
|
/**
|
* 获取图片尺寸和截图 工具类
|
*
|
* @author zhangxiaoyan
|
*/
|
@Slf4j
|
public class ImageSizeUtil {
|
|
|
/**
|
* 获取图片最长边长度
|
* @param params
|
* @return
|
*/
|
public static int getImageLengthOfSide(MultipartFile params){
|
int lengthSize = 0;
|
Map<String, Integer> result = new HashMap<>();
|
long beginTime = new Date().getTime();
|
// 获取图片格式
|
String suffixName = getSuffixNameInfo(params);
|
try {
|
Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(suffixName);
|
ImageReader reader = (ImageReader) readers.next();
|
ImageInputStream iis = ImageIO.createImageInputStream(params.getInputStream());
|
reader.setInput(iis, true);
|
result.put("width",reader.getWidth(0));
|
result.put("height",reader.getHeight(0));
|
if(reader.getWidth(0) > reader.getHeight(0)){
|
lengthSize = reader.getWidth(0);
|
}else{
|
lengthSize = reader.getHeight(0);
|
}
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
|
return lengthSize;
|
}
|
|
/**
|
* 获取图片格式
|
* @param params
|
* @return
|
*/
|
public static String getSuffixNameInfo(MultipartFile params){
|
String result = "";
|
// 图片后缀
|
String suffixName = params.getOriginalFilename().substring(
|
params.getOriginalFilename().lastIndexOf("."));
|
if(suffixName.indexOf("png")>0){
|
result = "png";
|
}else if(suffixName.indexOf("jpg")>0){
|
result = "jpg";
|
}else if(suffixName.indexOf("jpeg")>0){
|
result = "jpeg";
|
}
|
|
return result;
|
}
|
|
|
|
|
/**
|
* 根据指定大小压缩图片
|
*
|
* @param imageBytes 源图片字节数组
|
* @param desFileSize 指定图片大小,单位kb
|
* @return 压缩质量后的图片字节数组
|
*/
|
public static byte[] compressPicForScale(byte[] imageBytes, long desFileSize) {
|
if (imageBytes == null || imageBytes.length <= 0 || imageBytes.length < desFileSize * 1024) {
|
return imageBytes;
|
}
|
long srcSize = imageBytes.length;
|
double accuracy = getAccuracy(srcSize / 1024);
|
// double accuracy = 0.85;
|
try {
|
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();
|
}
|
log.info("【图片压缩】imageId={} | 图片原大小={}kb | 压缩后大小={}kb",
|
"", srcSize / 1024, imageBytes.length / 1024);
|
} catch (Exception e) {
|
log.error("【图片压缩】msg=图片压缩失败!", e);
|
}finally {
|
}
|
return imageBytes;
|
}
|
|
/**
|
* 自动调节精度(经验数值)
|
*
|
* @param size 源图片大小,单位kb
|
* @return 图片压缩质量比
|
*/
|
private static double getAccuracy(long size) {
|
double accuracy;
|
if (size < 900) {
|
accuracy = 0.85;
|
} else if (size < 2047) {
|
// accuracy = 0.6;
|
accuracy = 0.8;
|
} else if (size < 3275) {
|
// accuracy = 0.44;
|
accuracy = 0.7;
|
} else {
|
accuracy = 0.4;
|
}
|
return accuracy;
|
}
|
|
/**
|
* 压缩图片
|
* @return
|
*/
|
public static MultipartFile compressPic(MultipartFile multipartFile){
|
// 获取图片最长边
|
int imageLengthSize = ImageSizeUtil.getImageLengthOfSide(multipartFile);
|
// 获取图片大小
|
Long swd = multipartFile.getSize();
|
try {
|
InputStream inputStream = multipartFile.getInputStream();
|
// 图片压缩并返回字节数组
|
byte[] imgData = ImageSizeUtil.compressPicForScale(ToolsUtil.getByteArray(inputStream),2000);
|
// 转换回 multipartFile 文件
|
ByteArrayInputStream stream = new ByteArrayInputStream(imgData);
|
String fileName = multipartFile.getOriginalFilename() + System.currentTimeMillis() + ".jpg";
|
// 使用MinIO客户端上传图片
|
MockMultipartFile mockMultipartFile
|
= new MockMultipartFile("__init__.py", fileName, "application/octet-stream", stream);
|
// 关闭流
|
stream.close();
|
inputStream.close();
|
// 赋值
|
return mockMultipartFile;
|
} catch (IOException e) {
|
e.printStackTrace();
|
}finally {
|
// 流关闭
|
}
|
return null;
|
}
|
|
}
|