MultipartFile图片压缩简化

本文主要介绍如何简化MultipartFile压缩流程,使得调用者只需要简单的注解配置达到目的,传统的处理方式需要增加方法体中的代码,无法做到代码简洁。

经过一番思考,我决定利用spring的aop机制,完成配置自动化压缩的目的,我们知道aop主要有Before,Around,AfterReturning

我们在Around环绕方法中将post上来的MultipartFile进行分离压缩,并返还参数中。下面介绍一下具体代码实现如下:

@Around("webLog()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    assert attributes != null;
    HttpServletRequest request = attributes.getRequest();
    //首先获取方法名称列表
    MethodSignature msg = (MethodSignature) pjp.getSignature();
    //获取传入的参数
    Object[] args = pjp.getArgs();
    if (request.getMethod().equals("POST")) {
        compress(args, msg);
    }
    //返回
    return pjp.proceed(args);

}

自定义注解

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Compress {
    /**
     * 压缩目标大小,单位kb
     */
    long destSize();

    /**
     * 图片质量,0-1f
     */
    float quality();

    /**
     * 图片宽度
     */
    int width();

    /**
     * 图片高度
     */
    int height();
}
@SuppressWarnings("ResultOfMethodCallIgnored")
private void compress(Object[] objects, MethodSignature signature) throws IOException {
    //获取所有参数上的注解
    Annotation[][] parameterAnnotations = signature.getMethod().getParameterAnnotations();
    for (Annotation[] parameterAnnotation : parameterAnnotations) {
        int paramIndex = ArrayUtils.indexOf(parameterAnnotations, parameterAnnotation);
        for (Annotation annotation : parameterAnnotation) {
            if (annotation instanceof Compress) {
                Compress compress = (Compress) annotation;
                Object paramValue = objects[paramIndex];
                if (!(paramValue instanceof MultipartFile)) {
                    throw new RuntimeException("Compress can only  modified MultipartFile");
                }
                int width = compress.width();
                int height = compress.height();
                float quality = compress.quality();
                long destSize = compress.destSize();
                String destPath = IMAGE_PATH + "cache" + File.separator;
                File destFileDir = new File(destPath);
                if (!destFileDir.exists()) {
                    destFileDir.mkdir();
                }
                //进行压缩
                MultipartFile multipartFile = (MultipartFile) paramValue;
                File file = MultipartFileUtil.convertToFile(destPath + multipartFile.getOriginalFilename(), MultipartFileUtil.compressToSpecifySize(multipartFile.getBytes(), destSize, width, height, quality));
                objects[paramIndex] = MultipartFileUtil.parseMulFile(file.getAbsolutePath(), multipartFile.getName(), multipartFile.getOriginalFilename());
            }
        }
    }
}

文件处理工具类

import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.apache.commons.fileupload.FileItem;

import java.io.*;

public class MultipartFileUtil {

    /**
     * @param fileName      :文件名称
     * @param textFieldName 文件参数名称
     * @param picPath       :文件路径
     */
    public static MultipartFile parseMulFile(String picPath, String textFieldName, String fileName) {
        FileItem fileItem = createFileItem(picPath, textFieldName, fileName);
        return new CommonsMultipartFile(fileItem);
    }

    private static FileItem createFileItem(String filePath, String textFieldName, String fileName) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        int num = filePath.lastIndexOf(".");
        String extFile = filePath.substring(num);
        FileItem item = factory.createItem(textFieldName, "text/plain", true,
                fileName + extFile);
        File newfile = new File(filePath);
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(newfile);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192))
                    != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }

    public static File convertToFile(String filePath, byte[] fileByte) throws IOException {
        try (FileOutputStream stream = new FileOutputStream(filePath)) {
            stream.write(fileByte, 0, fileByte.length);
        }
        return new File(filePath);
    }

    public static byte[] compressToSpecifySize(byte[] fileByte, long desSize,int w,int h,float quality) throws IOException {
        desSize*=1024;
        try (ByteArrayInputStream inputStream = new ByteArrayInputStream(fileByte);
             ByteArrayOutputStream outputStream = new ByteArrayOutputStream(fileByte.length)) {
            while (fileByte.length > desSize) {
                Thumbnails.of(inputStream).size(w, h).outputQuality(quality).toOutputStream(outputStream);
                fileByte = outputStream.toByteArray();
            }
            return fileByte;
        }
    }

}

调用controller

@PostMapping("/compressImage")
public Result compressImage(@Compress(destSize = 100,width = 700,height  =600,quality = 0.9f) MultipartFile rootImage) {
 
    return Result.success();
}

这样配置完成就ok了,您只需配置该注解,就能自动进行压缩

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用Javajavax.imageio包来实现MultipartFile图片的压缩。下面是一个使用Spring MVC和MultipartFile进行图片压缩的示例代码: ```java import org.springframework.web.multipart.MultipartFile; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; public class ImageCompressor { public static void compressImage(MultipartFile file, String outputFilePath, int maxWidth, int maxHeight) throws IOException { BufferedImage image = ImageIO.read(file.getInputStream()); int originalWidth = image.getWidth(); int originalHeight = image.getHeight(); // 计算缩放比例 double scaleFactor = Math.min((double) maxWidth / originalWidth, (double) maxHeight / originalHeight); int newWidth = (int) (originalWidth * scaleFactor); int newHeight = (int) (originalHeight * scaleFactor); // 创建缩放后的图像 BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = resizedImage.createGraphics(); g2d.drawImage(image, 0, 0, newWidth, newHeight, null); g2d.dispose(); // 将缩放后的图像保存到文件 ImageIO.write(resizedImage, "jpg", new File(outputFilePath)); } } ``` 使用时,你可以在Spring MVC的controller中调用`compressImage`方法来实现图片压缩。需要传入要压缩MultipartFile对象、输出文件路径、以及期望的最大宽度和最大高度。 注意:上述示例代码仅适用于压缩JPEG格式的图片,如果需要处理其他格式的图片,可以根据需要进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值