图片无损压缩
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
/**
* 图片无损压缩
* @param image
* @return
*/
public String compressImage(String image) {
// 实现图片无损压缩的逻辑
//1.读取文件
BufferedImage bufferedImage = null;
try {
bufferedImage = convert(image);
} catch (IOException e) {
log.info("base64转换BufferedImage失败");
}
//压缩文件
if (bufferedImage != null) {
//模拟压缩 压缩质量(0.0f 最差质量,1.0f 最佳质量) 0.8
bufferedImage = compressImage(bufferedImage, 0.8);
}
//保存文件
if (bufferedImage != null) {
// try {
// saveImage(bufferedImage,downPath);
// } catch (IOException e) {
// log.info("图片压缩后保存失败");
// }
try {
image = convertImageToBase64(bufferedImage);
} catch (Exception e) {
log.info("BufferedImage转base64失败");
}
}
return image;
}
//base64转BufferedImage
public static BufferedImage convert(String base64Image) throws IOException {
// 解码Base64字符串
byte[] imageBytes = Base64.getDecoder().decode(base64Image);
// 创建字节数组输入流
ByteArrayInputStream bis = new ByteArrayInputStream(imageBytes);
// 通过ImageIO读取图片
BufferedImage image = ImageIO.read(bis);
// 关闭输入流
bis.close();
return image;
}
// 进行无损压缩
public BufferedImage compressImage(BufferedImage originalImage, double scale) {
int newWidth = (int) (originalImage.getWidth() * scale);
int newHeight = (int) (originalImage.getHeight() * scale);
// 创建压缩后的图片
BufferedImage compressedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = compressedImage.createGraphics();
// 绘制原始图片到压缩后的图片上
g2d.drawImage(originalImage, 0, 0, newWidth, newHeight, null);
g2d.dispose(); // 释放资源
return compressedImage;
}
//BufferedImage转base64
public String convertImageToBase64(BufferedImage image) throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", outputStream); // 假设我们使用PNG格式
byte[] imageBytes = outputStream.toByteArray();
String base64String = Base64.getEncoder().encodeToString(imageBytes);
outputStream.close();
return base64String;
}
图片尺寸大小调整
POM引入
<!-- 图片尺寸调整-->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.11</version>
</dependency>
工具类ThumbnailsUtils
import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class ThumbnailsUtils {
private static final Logger logger = LoggerFactory.getLogger(ThumbnailsUtils.class);
/**
* 通过BufferedImage图片流调整图片大小
*/
public static BufferedImage resizeImageOne(BufferedImage originalImage, int targetWidth, int targetHeight) throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Thumbnails.of(originalImage)
.size(targetWidth, targetHeight)
.outputFormat("JPEG")
.outputQuality(1)
.toOutputStream(outputStream);
byte[] data = outputStream.toByteArray();
ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
return ImageIO.read(inputStream);
}
/**
* BufferedImage图片流转byte[]数组
*/
public static byte[] imageToBytes(BufferedImage bImage) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
ImageIO.write(bImage, "jpg", out);
} catch (IOException e) {
logger.error("错误信息: ", e);
}
return out.toByteArray();
}
/**
* byte[]数组转BufferedImage图片流
*/
private static BufferedImage bytesToBufferedImage(byte[] ImageByte) {
ByteArrayInputStream in = new ByteArrayInputStream(ImageByte);
BufferedImage image = null;
try {
image = ImageIO.read(in);
} catch (IOException e) {
logger.error("错误信息: ", e);
}
return image;
}
}
尺寸调整
public String resizeImage(String image, int width, int height) {
// 实现图片大小调整的逻辑
//1.读取文件
BufferedImage bufferedImage = null;
try {
bufferedImage = convert(image);
} catch (IOException e) {
log.info("base64转换BufferedImage失败");
}
try {
bufferedImage = ThumbnailsUtils.resizeImageOne(bufferedImage, width, height);
} catch (Exception e) {
log.info("图片大小调整失败");
}
//保存文件
if (bufferedImage != null) {
// try {
// saveImage(bufferedImage,downPath);
// } catch (IOException e) {
// log.info("图片压缩后保存失败");
// }
try {
image = convertImageToBase64(bufferedImage);
} catch (Exception e) {
log.info("BufferedImage转base64失败");
}
}
return image;
}
其他常用工具类
验证文件是否为PDF或图片(JPG/PNG)格式。
/**
* 验证文件是否为PDF或图片(JPG/PNG)格式。
*
* @param filePath 文件的路径。
* @return 如果文件为PDF或图片格式则返回true,否则返回false。
*/
public static boolean isValidFileType(String filePath) {
// 创建File对象
File file = new File(filePath);
// 获取文件扩展名
String extension = getExtension(file);
// 验证扩展名
return "pdf".equalsIgnoreCase(extension) ||
"jpg".equalsIgnoreCase(extension) ||
"jpeg".equalsIgnoreCase(extension) ||
"png".equalsIgnoreCase(extension);
}
/**
* 获取文件的扩展名。
*
* @param file 文件对象。
* @return 文件的扩展名。
*/
private static String getExtension(File file) {
String fileName = file.getName();
int lastIndexOfDot = fileName.lastIndexOf('.');
if (lastIndexOfDot == -1) {
return ""; // 没有扩展名
}
return fileName.substring(lastIndexOfDot + 1);
}
图片文件处理工具类
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import org.apache.commons.io.IOUtils;
/**
* 目标处理的图片类别有:png,jpg,jpeg
*
* @author fmx
* @date 2024/08/23
*/
public class ImageConvertBase64 {
/**
* 将图片文件转化为 byte 数组
*
* @param image 待处理图片文件
* @return 图片文件转化为的byte数组
*/
public static byte[] toBytes(File image) {
try (FileInputStream input = new FileInputStream(image)) {
return IOUtils.toByteArray(input);
} catch (IOException e) {
return null;
}
}
public static String toBase64(byte[] bytes) {
return bytesEncode2Base64(bytes);
}
/**
* 将图片转化为 base64 的字符串
*
* @param image 待处理图片文件
* @return 图片文件转化出来的 base64 字符串
*/
public static String toBase64(File image) {
return toBase64(image, false);
}
/**
* 将图片转化为 base64
* 的字符串。如果<code>appendDataURLScheme</code>的值为true,则为图片的base64字符串拓展Data URL
* scheme。
*
* @param image 图片文件的路径
* @param appendDataURLScheme 是否拓展 Data URL scheme 前缀
* @return 图片文件转化为的base64字符串
*/
public static String toBase64(File image, boolean appendDataURLScheme) {
String imageBase64 = bytesEncode2Base64(toBytes(image));
if (appendDataURLScheme) {
imageBase64 = ImageDataURISchemeMapper.getScheme(image) + imageBase64;
}
return imageBase64;
}
private static String bytesEncode2Base64(byte[] bytes) {
return new String(Base64.getEncoder().encode(bytes), StandardCharsets.UTF_8);
}
private static byte[] base64Decode2Bytes(String base64) {
return Base64.getDecoder().decode(base64);
}
/**
* 将byte数组恢复为图片文件
*
* @param imageBytes 图片文件的 byte 数组
* @param imagePath 恢复的图片文件的保存地址
* @return 如果生成成功,则返回生成的文件路径,此时结果为参数的<code>imagePath</code>。否则返回 null
*/
public static File toImage(byte[] imageBytes, File imagePath) {
if (!imagePath.getParentFile().exists()) {
imagePath.getParentFile().mkdirs();
}
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(imagePath))) {
bos.write(imageBytes);
return imagePath;
} catch (IOException e) {
return null;
}
}
/**
* 将base64字符串恢复为图片文件
*
* @param imageBase64 图片文件的base64字符串
* @param imagePath 恢复的图片文件的保存地址
* @return 如果生成成功,则返回生成的文件路径,此时结果为参数的<code>imagePath</code>。。否则返回 null
*/
public static File toImage(String imageBase64, File imagePath) {
// base64 字符串中没有 ","
int firstComma = imageBase64.indexOf(",");
if (firstComma >= 0) {
imageBase64 = imageBase64.substring(firstComma + 1);
}
return toImage(base64Decode2Bytes(imageBase64), imagePath);
}
/**
* 保存 imageBase64
* 到指定文件中。如果<code>fileName</code>含有拓展名,则直接使用<code>fileName</code>的拓展名。 否则,如果
* <code>imageBase64</code> 为Data URLs,则更具前缀的来判断拓展名。如果无法判断拓展名,则使用“png”作为默认拓展名。
*
* @param imageBase64 图片的base64编码字符串
* @param dir 保存图片的目录
* @param fileName 图片的名称
* @return 如果生成成功,则返回生成的文件路径。否则返回 null
*/
public static File toImage(String imageBase64, File dir, String fileName) {
File imagePath = null;
if (fileName.indexOf(".") < 0) {
String extension = ImageDataURISchemeMapper.getExtensionFromImageBase64(imageBase64, "png");
imagePath = new File(dir, fileName + "." + extension);
} else {
imagePath = new File(dir, fileName);
}
return toImage(imageBase64, imagePath);
}
}