package com.nova.sankuai.infra.utils; 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 java.awt.*; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.WritableRaster; import java.io.*; import java.util.UUID; @Slf4j public class CompressImageUtil { /** * 按尺寸原比例缩放图片 * * @throws IOException */ public static MultipartFile imgThumb(MultipartFile file) throws Exception { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); Thumbnails.of(file.getInputStream()).size(100, 100).keepAspectRatio(false).toOutputStream(outputStream); byte[] bytes = outputStream.toByteArray(); InputStream inputStream = new ByteArrayInputStream(bytes); MultipartFile multipartFile = new MockMultipartFile(file.getOriginalFilename(), file.getOriginalFilename(), file.getContentType(), inputStream); return multipartFile; } /** * 按照比例进行缩放 * * @param source 输入源 * @param output 输出源 * @param scale 比例 * @throws IOException */ public static void imgScale(String source, String output, double scale) throws IOException { Thumbnails.of(source).scale(scale).toFile(output); } public static File transferToFile(MultipartFile multipartFile) { // 选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 。 File file = null; try { String originalFilename = multipartFile.getOriginalFilename(); String[] filename = originalFilename.split("\\."); file = File.createTempFile(filename[0], filename[1]); multipartFile.transferTo(file); file.deleteOnExit(); } catch (IOException e) { e.printStackTrace(); } return file; } /** * 等比例缩放 * * @param srcImg 原图 * @param destImg 目标保存位置 * @param proportion 压缩比例 */ public static String zoomImage(File srcImg, String destImg, Double proportion) { File exist = exist(srcImg, destImg); reSize(srcImg, exist, null, null, proportion); return exist.getName(); } /** * 固定长度缩放 * * @param srcImg 原图 * @param destImg 目标保存位置 * @param width 期望宽带 * @param height 期望长度 */ public static String zoomImage(File srcImg, String destImg, Integer width, Integer height) { File exist = exist(srcImg, destImg); reSize(srcImg, exist, width, height, null); return exist.getName(); } public static File exist(File srcImg, String destImg) { if (srcImg == null) { return null; } String fix = null; String name = srcImg.getName(); int i = name.indexOf("."); if (i > 0) { fix = name.substring(i); } name = UUID.randomUUID().toString() + fix; File file = new File(destImg + name); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } return file; } /** * @param srcImg 原图片 * @param destImg 目标位置 * @param width 期望宽 * @param height 期望高 * @param proportion 等比例(0.01-1)(等比例不为空是等比例优先) */ public static void reSize(File srcImg, File destImg, Integer width, Integer height, Double proportion) { String type = getImageType(srcImg); if (type == null) { return; } // if (width < 0 || height < 0) { // return; // } BufferedImage srcImage = null; try { srcImage = ImageIO.read(srcImg); System.out.println("srcImg size=" + srcImage.getWidth() + "X" + srcImage.getHeight()); } catch (IOException e) { e.printStackTrace(); return; } if (srcImage != null) { // targetW,targetH分别表示目标长和宽 BufferedImage target = null; Double sx = null; Double sy = null; // 等比缩放 if (proportion != null) { sx = sy = proportion; width = (int) (sx * srcImage.getWidth()); height = (int) (sy * srcImage.getHeight()); } else { sx = (double) width / srcImage.getWidth(); sy = (double) height / srcImage.getHeight(); } System.out.println("destImg size=" + width + "X" + height); ColorModel cm = srcImage.getColorModel(); WritableRaster raster = cm.createCompatibleWritableRaster(width, height); boolean alphaPremultiplied = cm.isAlphaPremultiplied(); target = new BufferedImage(cm, raster, alphaPremultiplied, null); Graphics2D g = target.createGraphics(); // smoother than exlax: g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g.drawRenderedImage(srcImage, AffineTransform.getScaleInstance(sx, sy)); g.dispose(); // 将转换后的图片保存 try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(target, type, baos); FileOutputStream fos = new FileOutputStream(destImg); fos.write(baos.toByteArray()); fos.flush(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 获取文件后缀不带. * * @param file 文件后缀名 * @return */ public static String getImageType(File file) { if (file != null && file.exists() && file.isFile()) { String fileName = file.getName(); int index = fileName.lastIndexOf("."); if (index != -1 && index < fileName.length() - 1) { return fileName.substring(index + 1); } } return null; } }