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 result = new HashMap<>(); long beginTime = new Date().getTime(); // 获取图片格式 String suffixName = getSuffixNameInfo(params); try { Iterator 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; } }