各种图片工具类:
imageConversion2ImgStream方法:将各种图片流裁剪生成矩形缩略图流形式。
bufferedConversion2ProgressiveJPEGStream:获取图片流和目标地址转换ProgressiveJPEG流。
imgType:可以判断图片类型。
所需依赖:
<!-- hutool工具包 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.18</version>
</dependency>
<!--webp格式图片-->
<dependency>
<groupId>org.sejda.imageio</groupId>
<artifactId>webp-imageio</artifactId>
<version>0.1.6</version>
</dependency>
ImageWUtil工具类:
import cn.hutool.core.img.Img;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Iterator;
import java.util.Locale;
/**
* @author: Wu ZiLin
* @create: 2023-09-06 16:14
* @description: 图片格式工具类
**/
public class ImageWUtil {
private ImageWUtil() {
}
/**
* 获取Img流和目标地址转换jpg,返回InputStream
*/
public static InputStream imageConversion2ImgStream(InputStream inputStream, String bufferType) {
try {
BufferedImage buffer = ImageIO.read(inputStream);
return bufferedConversion2ImgStream(buffer, bufferType);
} catch (IOException e) {
// IO流读取文件失败
throw new RuntimeException(e);
}
}
/**
* 获取图片流转换Img,并进行裁剪,返回InputStream
*/
public static InputStream bufferedConversion2ImgStream(BufferedImage buffer, String bufferType) {
try (ByteArrayOutputStream img = new ByteArrayOutputStream()) {
Rectangle r = "pdf".equals(bufferType) ? cropPdfPicture(0, 0, buffer.getWidth(), buffer.getHeight()) :
cropPicture(0, 0, buffer.getWidth(), buffer.getHeight());
Img.from(buffer)
.setPositionBaseCentre(false)
.cut(r)//裁剪规则,如果想不裁剪可以去掉
.setTargetImageType("jpg")
.setQuality(1)
.write(img);
// BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(img.toByteArray()));
return new ByteArrayInputStream(img.toByteArray());
} catch (Exception e) {
// IO流读取文件失败
throw new RuntimeException(e);
}
}
/**
* 获取图片流和目标地址转换ProgressiveJPEG,返回InputStream
*/
public static InputStream bufferedConversion2ProgressiveJPEGStream(InputStream inputStream) {
BufferedImage bufferedImage;
InputStream inputTempFile = null;
ImageOutputStream output = null;
ImageWriter writer = null;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream(37628)) {
bufferedImage = ImageIO.read(inputStream);
Iterator<ImageWriter> it = ImageIO.getImageWritersByFormatName("jpeg");
while (it.hasNext()) {
writer = it.next();
break;
}
if (writer != null) {
ImageWriteParam params = writer.getDefaultWriteParam();
params.setProgressiveMode(ImageWriteParam.MODE_DEFAULT);
// params.setCompressionQuality(0.8f);
output = ImageIO.createImageOutputStream(baos);
writer.setOutput(output);
writer.write(null, new IIOImage(bufferedImage, null, null), params);
output.flush();
inputTempFile = new ByteArrayInputStream(baos.toByteArray());
}
return inputTempFile;
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
output.close();
writer.dispose();
} catch (Exception e) {
}
}
}
/**
* 判断图片真实格式
*
* @param inputStream
* @return
*/
public static String imgType(InputStream inputStream) {
try {
// 读取文件前几位
byte[] fileHeader = new byte[4];
inputStream.read(fileHeader, 0, fileHeader.length);
inputStream.close();
// 转为十六进制字符串
StringBuilder sb = new StringBuilder();
for (byte b : fileHeader) {
String hex = Integer.toHexString(b & 0xff);
sb.append(hex.length() == 2 ? hex : ("0" + hex));
}
String header = sb.toString().toUpperCase(Locale.ROOT);
if (header.contains("FFD8FF")) {
return "jpg";
} else if (header.contains("89504E47")) {
return "png";
} else if (header.contains("47494638")) {
return "gif";
} else if (header.contains("424D")) {
return "bmp";
} else if (header.contains("52494646")) {
return "webp";
} else if (header.contains("49492A00")) {
return "tif";
}
return null;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 获取图片宽高裁剪图片大小
*/
private static Rectangle cropPicture(int x, int y, int width, int height) {
if (width > height) {
x = (width - height) / 2;
width = width - 2 * x;
} else {
y = (height - width) / 2;
height = height - 2 * y;
}
width = Math.min(width, height);
return new Rectangle(x, y, width, width);
}
/**
* 获取pdf图片宽高裁剪图片大小
*/
private static Rectangle cropPdfPicture(int x, int y, int width, int height) {
if (width > height) {
x = (width - height) / 2;
width = width - 2 * x;
}
width = Math.min(width, height);
return new Rectangle(x, y, width, width);
}
}
测试类:ImageWUtilTest
import cn.hutool.core.io.file.FileNameUtil;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import zut.wu.fileinstall.FileInstallDemoApplication;
import zut.wu.fileinstall.utils.ImageWUtil;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
//FileInstallDemoApplication.class 是我的启动类
@SpringBootTest(classes = FileInstallDemoApplication.class)
class ImageWUtilTest {
//打印图片到本地
@Test
void imageConversion2ImgTest() throws Exception {
String srcPic = "C:\\Users\\86131\\Desktop\\translate\\pic\\img-a.jpg";
//旧方法 InputStream srcPicStream = new FileInputStream(srcPic);
InputStream srcPicStream = Files.newInputStream(Paths.get(srcPic));
printImg(srcPicStream, getTongUrl(srcPic, "-thumb.jpg"));
}
//生成渐进式格式图片
@Test
void bufferedConversion2ProgressiveJPEGStreamTest() throws Exception {
String srcPic = "C:\\Users\\86131\\Desktop\\translate\\pic\\img-b.jpg";
InputStream srcPicStream = Files.newInputStream(Paths.get(srcPic));
//渐进图片
InputStream inputStream = ImageWUtil.bufferedConversion2ProgressiveJPEGStream(srcPicStream);
//输出图片
printImg(inputStream, getTongUrl(srcPic, "-thumb.jpg"));
}
//判断图片真实格式
@Test
void img2imgTypeTest() throws Exception {
String srcPic = "C:\\Users\\86131\\Desktop\\translate\\pic\\img-webp.jpg";
InputStream srcPicStream = new FileInputStream(srcPic);
String imgType = ImageWUtil.imgType(srcPicStream);
if (imgType != null || imgType.length() > 0) {
System.out.println("imgType = " + imgType);
}
}
//图片生成缩略图到本地
@Test
void bufferedConversion2ImgStreamTest() throws Exception {
String srcPic = "C:\\Users\\86131\\Desktop\\translate\\pic\\img-c.jpg";
InputStream srcPicStream = Files.newInputStream(Paths.get(srcPic));
//生成图片缩略图
InputStream inputImageStream = ImageWUtil.imageConversion2ImgStream(srcPicStream, "image");
//输出图片
printImg(inputImageStream, getTongUrl(srcPic, "-thumb.jpg"));
}
/**
* 根据地址生成同级地址+suffix
*/
private String getTongUrl(String srcPath, String suffix) {
//获取文件后缀
String srcSuffix = FileNameUtil.getSuffix(srcPath).toLowerCase();
return srcPath.substring(0, srcPath.length() - srcSuffix.length() - 1) + suffix;
}
/**
* 打印图片
*/
public static void printImg(InputStream inputStream, String tarPath)throws Exception {
printImg(ImageIO.read(inputStream), tarPath);
}
/**
* 打印图片
*/
public static void printImg(BufferedImage bufferedImage, String tarPath) throws Exception{
ImageIO.write(bufferedImage, "jpg", new File(tarPath));
System.out.println("打印图片成功");
}
}
测试结果: