图片压缩处理工具类

前言:
关于图片压缩需要考虑如下因素:
b>图片的大小(M)限制
c>图片尺寸(宽高)限制
c>图片(大小、尺寸)不需要处理
e>图片清晰度与大小、尺寸的矛盾处理
f>Spring中MultipartFile与原生File的转化及byte字符流处理 


1.压缩处理工具类如下:

package com.worm.util;

import com.ding.framwork.util.secure.MD5Tool;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.entity.ContentType;
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.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.util.UUID;

/**
 * 图片处理工具类
 * @author learnworm
 * @version 2020-12-10 上午10:07:13
 */
public class ImageUtil {
    //默认素材宽
    private final static int DEFAULT_MATERIAL_IMG_WIDTH = 1280;
    //默认素材高
    private final static int DEFAULT_MATERIAL_IMG_HEIGHT = 1920;
	//默认大小限制(1M)
	private final static long DEFAULT_MATERIAL_IMG_SIZE = 1024*1024;

	 public static void main(String[] args) throws  IOException{
		String path1 = "D:\\tmp\\mu3.jpg";
		File file = new File(path1);
		MultipartFile multipartFile = filtToMuti(file);
		String materialUrl = multipartFile.getOriginalFilename();
		byte[] bytes = ImageUtil.imgCompress(multipartFile);
		String digest = MD5Tool.getFileMD5(ImageUtil.byteToFile(bytes, ImageUtil.getSufix(materialUrl)));
		writeFile(bytes, "D:\\tmp\\sub", materialUrl);
		System.out.println("--------1----------^"+digest+"====="+materialUrl);
	}

	/**
	 * 文件Md5签名
	 * @param bytes
	 * @param originalUrl
	 * @return
	 */
	public static String digistMd5(byte[] bytes,String originalUrl){
		try {
			return MD5Tool.getFileMD5(ImageUtil.byteToFile(bytes, ImageUtil.getSufix(originalUrl)));
		}catch (IOException ioe){
			ioe.printStackTrace();
			return null;
		}
	}

	/**
	 * 图片压缩处理
	 * @param mutiFile
	 * @return
	 */
	public static byte[] imgCompress(MultipartFile mutiFile){
		byte[] bytes = null;
		//转File类型文件
	 	File file = mutiToFile(mutiFile);
		//图片后缀
		String sufix = getSufix(mutiFile.getName());
		//图片大小
		long len = mutiFile.getSize();
		//图片尺寸
		boolean size = isResize(file,DEFAULT_MATERIAL_IMG_WIDTH,DEFAULT_MATERIAL_IMG_HEIGHT);
		try {
			File rfile = null;
			bytes = mutiFile.getBytes();
			if(size){//限制尺寸大小
				BufferedImage bimg = imgCompressResize(file,DEFAULT_MATERIAL_IMG_WIDTH,DEFAULT_MATERIAL_IMG_HEIGHT);
				String bName = UUID.randomUUID().toString();
				File tmpDirFile = Files.createTempDirectory("tempFile").toFile();
				rfile = File.createTempFile(bName, sufix, tmpDirFile);
				ImageIO.write(bimg, getSufix(mutiFile.getName()), rfile);
				bytes = getImgBytes(rfile);
				//重新计算大小
				mutiFile = byteToMuti(bytes);
				len = mutiFile.getSize();
			}
			if(len>DEFAULT_MATERIAL_IMG_SIZE){//保持清晰度
				bytes = imgCompressQuality(mutiFile.getBytes(),DEFAULT_MATERIAL_IMG_SIZE,sufix);
				//重新计算大小
				mutiFile = byteToMuti(bytes);
				len = mutiFile.getSize();
			}
			if(len>DEFAULT_MATERIAL_IMG_SIZE){//严格限制到指定大小
				bytes = imgCompressLen(mutiFile.getBytes(),DEFAULT_MATERIAL_IMG_SIZE,sufix);
			}
			if(rfile!=null && rfile.exists()){
				rfile.delete();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return bytes;
	}

	/**
	 * 图片压缩算法-清淅度
	 * @param input
	 * @param maxLen 最大
	 * @return
	 * @throws IOException
	 */
	public static byte[] imgCompressQuality(byte[] input,long maxLen,String sufix) throws IOException {
		if(input.length < maxLen){
			return input;
		}
		if (StringUtils.isEmpty(sufix)){//如果空则默认jpg
			sufix = "jpg";
		}
		float quality = 1.0f;
		float scale = 1.0f;
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		InputStream is = new ByteArrayInputStream(input);
		Thumbnails.of(is).scale(scale).outputQuality(quality).outputFormat(sufix).toOutputStream(os);
		byte[] result = os.toByteArray();
		while(result.length > maxLen && quality > 0.399){//保清晰度
			is.close();
			is = new ByteArrayInputStream(input);
			os.close();
			os = new ByteArrayOutputStream();
			quality = quality - 0.05f;
			Thumbnails.of(is).scale(scale).outputQuality(quality).outputFormat(sufix).toOutputStream(os);
			result = os.toByteArray();
		}
		return result;
	}

	/**
	 * 图片压缩-大小M
	 * @param input
	 * @param maxLen 大小
	 * @return
	 * @throws IOException
	 */
	public static byte[] imgCompressLen(byte[] input,long maxLen,String sufix) throws IOException {
		if(input.length < maxLen){
			return input;
		}
		if (StringUtils.isEmpty(sufix)){//如果空则默认jpg
			sufix = "jpg";
		}
		float quality = 1.0f;
		float scale = 1.0f;
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		InputStream is = new ByteArrayInputStream(input);
		Thumbnails.of(is).scale(scale).outputQuality(quality).outputFormat(sufix).toOutputStream(os);
		byte[] result = os.toByteArray();
		while(result.length > maxLen){//限制大小
			is.close();
			is = new ByteArrayInputStream(input);
			os.close();
			os = new ByteArrayOutputStream();
			quality = quality - 0.05f;
			Thumbnails.of(is).scale(scale).outputQuality(quality).outputFormat(sufix).toOutputStream(os);
			result = os.toByteArray();
			byte[] tmpbyte = os.toByteArray();
		}
		return result;
	}

	/**
	 * @desc 图片缩放
	 * @param file 图片
	 * @param defWidth 宽度
	 * @param defHeight 高度
	 */
	public static BufferedImage imgCompressResize(File file, int defWidth, int defHeight) {
		try {
			double ratio = 1; // 缩放比例
			BufferedImage bi = ImageIO.read(file);
			Image itemp = bi.getScaledInstance(defWidth, defHeight,Image.SCALE_SMOOTH);
			int imgWidth = bi.getWidth();
			int imgHeight = bi.getHeight();
			//宽高需要处理
			if(imgWidth > defWidth && imgHeight > defHeight) {
				double ratioW = (new Integer(defWidth)).doubleValue()/imgWidth;
				double ratioH = (new Integer(defHeight)).doubleValue()/imgHeight;
				if(ratioW < ratioH) {
					ratio = ratioW;
				}else {
					ratio = ratioH;
				}
				AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);
				itemp = op.filter(bi, null);
			}
			return (BufferedImage) itemp;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @desc 图片缩放
	 * @param file 图片
	 * @param defWidth 宽度
	 * @param defHeight 高度
	 * @return boolean
	 */
	public static boolean isResize(File file, int defWidth, int defHeight) {
		try {
			BufferedImage bi = ImageIO.read(file);
			int imgWidth = bi.getWidth();
			int imgHeight = bi.getHeight();
			//宽高是否符合要求
			if(imgWidth > defWidth && imgHeight > defHeight) {
				return true;
			}
			return false;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 图片补白
	 * @param file 图片
	 * @param defWidth 宽
	 * param  defHeight 高
	 */
	public static BufferedImage imgFiller(File file, int defWidth, int defHeight) {
		try {
			BufferedImage bi = ImageIO.read(file);
			Image itemp = bi.getScaledInstance(defWidth, defHeight,Image.SCALE_SMOOTH);
			int imgWidth = bi.getWidth();
			int imgHeight = bi.getHeight();
			BufferedImage image = new BufferedImage(defWidth, defHeight,
					BufferedImage.TYPE_INT_RGB);
			Graphics2D g = image.createGraphics();
			g.setColor(Color.white);
			g.fillRect(0, 0, defWidth, defHeight);
			if (defWidth == itemp.getWidth(null))
				g.drawImage(itemp, 0, (defHeight - itemp.getHeight(null)) / 2,
						itemp.getWidth(null), itemp.getHeight(null),
						Color.white, null);
			else
				g.drawImage(itemp, (defWidth - itemp.getWidth(null)) / 2, 0,
						itemp.getWidth(null), itemp.getHeight(null),
						Color.white, null);
			g.dispose();
			itemp = image;
			return (BufferedImage) itemp;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 得到文件字节流
	 * @param file
	 * @return
	 */
	public static byte[] getImgBytes(File file){
		byte[] buffer = null;
		try {
			FileInputStream fis = new FileInputStream(file);
			ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
			byte[] b = new byte[1000];
			int n;
			while ((n = fis.read(b)) != -1) {
				bos.write(b, 0, n);
			}
			fis.close();
			bos.close();
			buffer = bos.toByteArray();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return buffer;
	}

	/**
	 * @desc 字节流转文件
	 * @param bytes
	 * @param ext
	 * @return
	 * @throws IOException
	 */
	public static File byteToFile(byte[] bytes,String ext) throws IOException {
		ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
		String fileName = UUID.randomUUID().toString();
		File tmpDirFile = Files.createTempDirectory("tempFile").toFile();
		File resultFile = File.createTempFile(fileName, '.' + ext, tmpDirFile);
		resultFile.deleteOnExit();
		org.apache.commons.io.FileUtils.copyInputStreamToFile(inputStream, resultFile);
		return resultFile;
	}

	/**
	 * 生成文件
	 * @param bfile
	 * @param filePath
	 * @param fileName
	 */
	public static void writeFile(byte[] bfile, String filePath,String fileName) {
		BufferedOutputStream bos = null;
		FileOutputStream fos = null;
		File file = null;
		try {
			File dir = new File(filePath);
			if(!dir.exists()&&dir.isDirectory()){//判断文件目录是否存在
				dir.mkdirs();
			}
			file = new File(filePath+"\\"+fileName);
			fos = new FileOutputStream(file);
			bos = new BufferedOutputStream(fos);
			bos.write(bfile);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (bos != null) {
				try {
					bos.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

	/**
	 * MultipartFile转化File
	 * @param mFile
	 * @return
	 */
	public static File mutiToFile(MultipartFile mFile) {
		File file = new File(mFile.getOriginalFilename());
		try {
			org.apache.commons.io.FileUtils.copyInputStreamToFile(mFile.getInputStream(), file);
			return file;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * File转化MultipartFile
	 * @param file
	 * @return MultipartFile
	 */
	public static MultipartFile filtToMuti(File file) {
		FileInputStream input;
		try {
			input = new FileInputStream(file);
			MultipartFile multipartFile;
			multipartFile = new MockMultipartFile(file.getName(), file.getName(), "text/plain", IOUtils.toByteArray(input));
			return multipartFile;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * byte转化MultipartFile
	 * @param bytes
	 * @return MultipartFile
	 */
	public static MultipartFile byteToMuti(byte[] bytes) {
		InputStream  input;
		try {
			byte[] fileByte = new byte[bytes.length];
			input = new ByteArrayInputStream(fileByte);
			MultipartFile multipartFile;
			multipartFile = new MockMultipartFile(ContentType.APPLICATION_OCTET_STREAM.toString(), input);
			return multipartFile;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取文件后缀
	 * @param filename
	 * @return
	 */
	public static String getSufix(String filename) {
		if ((filename != null) && (filename.length() > 0)) {
			int dot = filename.lastIndexOf('.');
			if ((dot >-1) && (dot < (filename.length() - 1))) {
				return filename.substring(dot + 1);
			}
		}
		return "";
	}
}

2. 需要配置引入的包

<!-- 图片压缩 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-mock</artifactId>
    <version>2.0.8</version>
</dependency>
<dependency>
    <groupId>net.coobird</groupId>
    <artifactId>thumbnailator</artifactId>
    <version>0.4.8</version>
</dependency>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值