Java - 图片压缩

Java - 图片压缩,第1张

前言:

  • 压缩时间较长, 5M左右的图片压缩至500k左右大概需要2秒左右;
  • Demo中返回base64字符串, 可根据自己需求改返回值类型;

环境:

  • JDK 1.8
  • IDEA 2021.3

注意:

  • 本人只测试了两种类型的图片(jpg/png),其他类型还需自行测试;
  • png类型的图片有点特殊,只能用另个开源组件进行压缩;
具体请看代码:


    net.coobird
    thumbnailator
    0.4.8




    org.jpedal
    OpenViewerFX
    6.6.14

import com.idrsolutions.image.png.PngCompressor;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import java.io.*;
import java.util.Base64;
import java.util.Optional;

/**
 * 图片工具类
 */
@Slf4j
public class ImageUtil {

    /**
     *  压缩图片,返回base64字符串
     *  接收MultipartFile格式文件;
     * @param multipartFile
     * @return
     * @throws Exception
     */
    public static String compressImageByMultipartFile(MultipartFile multipartFile) throws Exception {
        File sourceFile = MultipartFileToFile(multipartFile);
        return compressImageByFile(sourceFile);
    }

    /**
     * 将MultipartFile转换为File
     */
    public static File MultipartFileToFile(MultipartFile multiFile) throws IOException {
        String fileName = multiFile.getOriginalFilename();
        String prefix = fileName.substring(fileName.lastIndexOf("."));
        InputStream in = null;
        OutputStream out = null;
        try {
            File file = File.createTempFile(fileName, prefix);
            out = new FileOutputStream(file);
            in = multiFile.getInputStream();
            int read = 0;
            byte[] buffer = new byte[1024];
            while ((read = in.read(buffer, 0, 1024)) != -1) {
                out.write(buffer, 0, read);
            }
            return file;
        } catch (Exception e) {
            throw e;
        }finally {
            if (in != null){
                in.close();
            }
            if (out != null){
                out.close();
            }
        }
    }

    /**
     * 压缩jpg图片,返回base64字符串
     * sourceFile: 源文件;
     */
    public static String compressImageByFile(File sourceFile) throws Exception {
        log.info("原文件大小:[{}]",sourceFile.length());
        InputStream in = null;
        ByteArrayOutputStream out = null;
        try {
            //大于500K进行压缩:
            if (sourceFile.length() > 500 * 1024) {
                String fileName = sourceFile.getName();
                String prefix = fileName.substring(fileName.lastIndexOf(".")+1);
                if ("png".equals(prefix.toLowerCase())){
                    PngCompressor.compress(sourceFile,sourceFile);
                }else {
                    //sourceFile = getCompressFile(sourceFile,0.15f);
                    Thumbnails.of(sourceFile).scale(1f).outputQuality(0.1f).toFile(sourceFile);
                }
                log.info("文件格式:[{}] -- 压缩后文件大小:[{}]",prefix,sourceFile.length());
            }

            in = new FileInputStream(sourceFile);
            out = new ByteArrayOutputStream();
            int read = 0;
            byte[] buffer = new byte[1024];
            while ((read = in.read(buffer, 0, 1024)) != -1) {
                out.write(buffer, 0, read);
            }
            return Base64.getEncoder().encodeToString(out.toByteArray());
        } catch (IOException e) {
            throw e;
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null){
                out.close();
            }
        }
    }

    /**
     * 如果接口超时时间允许,也可以递归处理压缩,以至于达到最理想的压缩大小;
     * @param file
     * @param quality
     * @return
     * @throws IOException
     */
    private static File getCompressFile(File file,float quality) throws IOException {
        Thumbnails.of(file).scale(1f).outputQuality(quality).toFile(file);
        if(quality <= 0.1f || file.length() <= 500 * 1024){
            return file;
        }else{
            quality = quality - 0.05f;
            return getCompressFile(file,quality);
        }
    }
}

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;

@RestController
public class ImageDemoController {

    /** main方法测试 */
    public static void main(String[] args) {
        try {
            File file = new File("C:/原图片.jpg");
            String s = ImageUtil.compressImageByFile(file);
            System.out.println("压缩后图片的base64字符串::" + s);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /** 项目中测试 */
    @PostMapping("/test/compressImage")
    public  String compressImage(MultipartFile file){
        try {
            String s = ImageUtil.compressImageByMultipartFile(file);
            System.out.println("压缩后图片的base64字符串::" + s);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return "成功";
    }

}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/874475.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存