Java MultipartFile 批量设置图片大小 设置为指定大小范围 图片流(MultipartFile)压缩至指定大小

 maven

		<!--图片压缩-->
		<dependency>
			<groupId>net.coobird</groupId>
			<artifactId>thumbnailator</artifactId>
			<version>0.4.13</version> <!-- 使用最新版本 -->
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
		</dependency>

java 

package com.sun.basic.newImgName.utils;

import net.coobird.thumbnailator.Thumbnails;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class FileUtil {

    /**
     * BufferedImage转MultipartFile
     */
    public static MultipartFile convert(BufferedImage bufferedImage, String fileName, String contentType) throws IOException {
        // 将BufferedImage写入到字节数组输出流中
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "jpg", baos); // 假设你正在写入一个JPEG文件
        byte[] fileContent = baos.toByteArray();
        return ByteToMultipartFile(fileContent, fileName, contentType);
    }


    /** byte 转 BufferedImage转MultipartFile **/
    public static MultipartFile ByteToMultipartFile(byte[] bytes, String fileName, String contentType) throws IOException {
        MultipartFile multipartFile = new MockMultipartFile(
            fileName, // 原始文件名
            fileName, // 存储时的文件名
            contentType, // 文件内容类型
            bytes // 文件内容
        );
        return multipartFile;
    }

    /** 图片递归压缩 ---  提高效率:二分(未使用) **/
    public static MultipartFile compressImage(MultipartFile file, long maxSize, double scale) throws IOException {
        // 读取图片到BufferedImage
        BufferedImage image = ImageIO.read(file.getInputStream());
        // 初始压缩质量(范围0-1,1为最高质量)
        double quality = 0.9;
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        String outputFormat = "jpg"; // 指定输出格式为jpg
        // 统计循环次数
        int count = 0;
        byte[] compressedBytes;
        double qualityStep = 0.1;
        // 循环压缩直到图片大小满足要求
        while (true) {
            count ++;
            // 使用Thumbnailator进行压缩
            Thumbnails.of(image)
                .scale(scale) // 保持原尺寸
                .outputQuality(quality) // 设置输出质量
                .outputFormat(outputFormat)
                .toOutputStream(outputStream);

            compressedBytes = outputStream.toByteArray();
            long size = compressedBytes.length;
            // 如果图片大小满足要求,则退出循环
            if (size / 1024 <= maxSize) {
                break;
            }

            // 否则降低压缩质量并清空输出流以进行下一次压缩
            outputStream.reset();

            // 更新压缩质量
            quality -= qualityStep;
            if (quality < qualityStep * 2) {
                qualityStep /= 10;
            }
            if (count == 7) {
                return ByteToMultipartFile(compressedBytes, System.currentTimeMillis()+".jpg", "image/jpeg");
            }
        }
        return ByteToMultipartFile(compressedBytes, System.currentTimeMillis()+".jpg", "image/jpeg");

    }


    /**
     * 图片压缩至指定大小以下
     * @param file 文件流
     * @param maxSize 最大kb
     * @param minSize 最小kb
     * @return
     * @throws IOException
     */
    public static MultipartFile compressImageToMaxSize(MultipartFile file, long maxSize, long minSize) throws IOException {
        int n= 0;
        double scale = 1.0;
        double size = file.getSize() / 1024;
        if (size > 1024) scale = 1.0 - size / 1024 < 0.3 ? 0.3 : 1.0 - size / 1024;
        while (scale > 0.2) {
            if (size < minSize) {
                scale += 0.2;
            }else if (size < maxSize) {
                break;
            }
            file = compressImage(file, maxSize, scale);
            size = file.getSize() / 1024;
            scale -= 0.1;
        }
        if (size > maxSize) {
            throw new IOException(file.getName()+file.getSize()+"图片过大!请压缩至50-200kb内");
        }
        if (size < minSize) {
            throw new IOException(file.getName()+file.getSize()+"图片太小!请上传50-200kb的人脸照片");
        }
        return file;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

攀小黑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值