功能描述
ps: 支持本地生成文件和文件流
- 图片格式转换
- 图片压缩
- 图片裁剪
- 图片尺寸缩小
- 图片尺寸放大
- 图片尺寸重置
- 图片灰化
- 添加文字水印
- 添加图片水印
工具类
package com.qiangesoft.image.utils;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;
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.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.*;
import java.util.Iterator;
/**
* 图片操作
*
* @author qiangesoft
* @date 2024-04-26
*/
public class ImageOperateUtil {
/**
* 图片格式转换
*
* @param sourcePath
* @param targetPath
* @throws IOException
*/
public static void convert(String sourcePath, String targetPath) throws IOException {
String fileType = targetPath.substring(targetPath.lastIndexOf(".") + 1);
try (FileInputStream fis = new FileInputStream(sourcePath);
ImageOutputStream ios = ImageIO.createImageOutputStream(new File(targetPath))) {
convert(fis, ios, fileType);
}
}
/**
* 图片格式转换
*
* @param file
* @param outputStream
* @param fileType
* @throws IOException
*/
public static void convert(MultipartFile file, OutputStream outputStream, String fileType) throws IOException {
try (ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream);
InputStream inputStream = file.getInputStream()) {
convert(inputStream, ios, fileType);
}
}
private static void convert(InputStream inputStream, ImageOutputStream outputStream, String fileType) throws IOException {
// 获取ImageWriter
Iterator<ImageWriter> writerIterator = ImageIO.getImageWritersByFormatName(fileType);
Assert.isTrue(writerIterator.hasNext(), "图片文件格式错误");
ImageWriter writer = writerIterator.next();
// 写入图片
writer.setOutput(outputStream);
BufferedImage image = ImageIO.read(inputStream);
writer.write(null, new IIOImage(image, null, null), null);
}
/**
* 压缩图片
*
* @param sourcePath
* @param targetPath
* @param quality
* @throws IOException
*/
public static void compress(String sourcePath, String targetPath, float quality) throws IOException {
String fileType = targetPath.substring(targetPath.lastIndexOf(".") + 1);
try (FileInputStream fis = new FileInputStream(sourcePath);
ImageOutputStream ios = ImageIO.createImageOutputStream(new File(targetPath))) {
compress(fis, ios, fileType, quality);
}
}
/**
* 压缩图片
*
* @param file
* @param outputStream
* @param quality
* @throws IOException
*/
public static void compress(MultipartFile file, OutputStream outputStream, float quality) throws IOException {
String originalFilename = file.getOriginalFilename();
Assert.notNull(originalFilename, "文件非法");
String fileType = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
try (ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream);
InputStream inputStream = file.getInputStream()) {
compress(inputStream, ios, fileType, quality);
}
}
private static void compress(InputStream inputStream, ImageOutputStream outputStream, String fileType, float quality) throws IOException {
// 获取ImageWriter
Iterator<ImageWriter> writerIterator = ImageIO.getImageWritersByFormatName(fileType);
Assert.isTrue(writerIterator.hasNext(), "图片文件格式错误");
ImageWriter writer = writerIterator.next();
// 设置写入参数
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(quality);
// 写入图片
writer.setOutput(outputStream);
BufferedImage image = ImageIO.read(inputStream);
writer.write(null, new IIOImage(image, null, null), iwp);
}
/**
* 裁剪图片
*
* @param sourcePath
* @param targetPath
* @param width
* @param height
* @throws IOException
*/
public static void crop(String sourcePath, String targetPath, int width, int height) throws IOException {
crop(sourcePath, targetPath, 0, 0, width, height);
}
public static void crop(String sourcePath, String targetPath, int x, int y, int width, int height) throws IOException {
String targetType = targetPath.substring(targetPath.lastIndexOf(".") + 1);
try (FileInputStream fis = new FileInputStream(sourcePath);
FileOutputStream fos = new FileOutputStream(targetPath)) {
crop(fis, fos, targetType, x, y, width, height);
}
}
/**
* 裁剪图片
*
* @param file
* @param outputStream
* @param width
* @param height
* @throws IOException
*/
public static void crop(MultipartFile file, OutputStream outputStream, int width, int height) throws IOException {
crop(file, outputStream, 0, 0, width, height);
}
public static void crop(MultipartFile file, OutputStream outputStream, int x, int y, int width, int height) throws IOException {
String originalFilename = file.getOriginalFilename();
Assert.notNull(originalFilename, "文件非法");
String sourceType = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
try (InputStream inputStream = file.getInputStream()) {
crop(inputStream, outputStream, sourceType, x, y, width, height);
}
}
private static void crop(InputStream inputStream, OutputStream outputStream, String targetType, int x, int y, int width, int height) throws IOException {
// 读取图片
BufferedImage image = ImageIO.read(inputStream);
int maxWidth = image.getWidth();
Assert.isTrue(maxWidth > x + width, "图片宽度不足");
int maxHeight = image.getHeight();
Assert.isTrue(maxHeight > y + height, "图片高度不足");
// 裁剪图片
BufferedImage destImage = image.getSubimage(x, y, width, height);
// 保存新图片
ImageIO.write(destImage, targetType, outputStream);
}
/**
* 按倍率缩小图片
*
* @param sourcePath
* @param targetPath
* @param ratio
* @throws IOException
*/
public static void reduceByRatio(String sourcePath, String targetPath, int ratio) throws IOException {
String fileType = targetPath.substring(targetPath.lastIndexOf(".") + 1);
try (FileInputStream inputStream = new FileInputStream(sourcePath);
FileOutputStream outputStream = new FileOutputStream(targetPath)) {
reduceByRatio(inputStream, outputStream, ratio, fileType);
}
}
/**
* 按倍率缩小图片
*
* @param file
* @param outputStream
* @param ratio
* @throws IOException
*/
public static void reduceByRatio(MultipartFile file, OutputStream outputStream, int ratio) throws IOException {
String originalFilename = file.getOriginalFilename();
Assert.notNull(originalFilename, "文件非法");
String fileType = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
try (InputStream inputStream = file.getInputStream()) {
reduceByRatio(inputStream, outputStream, ratio, fileType);
}
}
private static void reduceByRatio(InputStream inputStream, OutputStream outputStream, int ratio, String sourceType) throws IOException {
// 构造Image对象
BufferedImage sourceImage = ImageIO.read(inputStream);
int width = sourceImage.getWidth() / ratio;
int height = sourceImage.getHeight() / ratio;
resize(sourceImage, outputStream, width, height, sourceType);
}
/**
* 按倍率放大图片
*
* @param sourcePath
* @param targetPath
* @param ratio
* @throws IOException
*/
public static void enlargeByRatio(String sourcePath, String targetPath, int ratio) throws IOException {
String fileType = targetPath.substring(targetPath.lastIndexOf(".") + 1);
try (FileInputStream inputStream = new FileInputStream(sourcePath);
FileOutputStream outputStream = new FileOutputStream(targetPath)) {
enlargeByRatio(inputStream, outputStream, ratio, fileType);
}
}
/**
* 按倍率放大图片
*
* @param file
* @param outputStream
* @param ratio
* @throws IOException
*/
public static void enlargeByRatio(MultipartFile file, OutputStream outputStream, int ratio) throws IOException {
String originalFilename = file.getOriginalFilename();
Assert.notNull(originalFilename, "文件非法");
String fileType = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
try (InputStream inputStream = file.getInputStream()) {
enlargeByRatio(inputStream, outputStream, ratio, fileType);
}
}
private static void enlargeByRatio(InputStream inputStream, OutputStream outputStream, int ratio, String fileType) throws IOException {
// 构造Image对象
BufferedImage sourceImage = ImageIO.read(inputStream);
int width = sourceImage.getWidth() * ratio;
int height = sourceImage.getHeight() * ratio;
resize(sourceImage, outputStream, width, height, fileType);
}
/**
* 按倍率放大图片
*
* @param sourcePath
* @param targetPath
* @param width
* @param height
* @throws IOException
*/
public static void resize(String sourcePath, String targetPath, int width, int height) throws IOException {
String fileType = targetPath.substring(targetPath.lastIndexOf(".") + 1);
try (FileInputStream inputStream = new FileInputStream(sourcePath);
FileOutputStream outputStream = new FileOutputStream(targetPath)) {
// 构造Image对象
BufferedImage sourceImage = ImageIO.read(inputStream);
resize(sourceImage, outputStream, width, height, fileType);
}
}
/**
* 按倍率放大图片
*
* @param file
* @param outputStream
* @param width
* @param height
* @throws IOException
*/
public static void resize(MultipartFile file, OutputStream outputStream, int width, int height) throws IOException {
String originalFilename = file.getOriginalFilename();
Assert.notNull(originalFilename, "文件非法");
String fileType = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
try (InputStream inputStream = file.getInputStream()) {
// 构造Image对象
BufferedImage sourceImage = ImageIO.read(inputStream);
resize(sourceImage, outputStream, width, height, fileType);
}
}
private static void resize(BufferedImage sourceImage, OutputStream outputStream, int width, int height, String fileType) throws IOException {
// 创建图片
BufferedImage targetImage = new BufferedImage(width, height, sourceImage.getType());
Graphics2D g2d = targetImage.createGraphics();
// 设置宽高
g2d.drawImage(sourceImage, 0, 0, width, height, null);
g2d.dispose();
// 保存新图片
ImageIO.write(targetImage, fileType, outputStream);
}
/**
* 图片灰化
*
* @param sourcePath
* @param targetPath
* @throws IOException
*/
public static void gray(String sourcePath, String targetPath) throws IOException {
String fileType = targetPath.substring(targetPath.lastIndexOf(".") + 1);
try (FileInputStream inputStream = new FileInputStream(sourcePath);
FileOutputStream outputStream = new FileOutputStream(targetPath)) {
gray(inputStream, outputStream, fileType);
}
}
/**
* 图片灰化
*
* @param file
* @param outputStream
* @throws IOException
*/
public static void gray(MultipartFile file, OutputStream outputStream) throws IOException {
String originalFilename = file.getOriginalFilename();
Assert.notNull(originalFilename, "文件非法");
String fileType = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
try (InputStream inputStream = file.getInputStream()) {
gray(inputStream, outputStream, fileType);
}
}
private static void gray(InputStream inputStream, OutputStream outputStream, String fileType) throws IOException {
// 读取图片
BufferedImage bufferedImage = ImageIO.read(inputStream);
// 灰化
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorConvertOp op = new ColorConvertOp(cs, null);
BufferedImage newBufferedImage = op.filter(bufferedImage, null);
// 保存新图片
ImageIO.write(newBufferedImage, fileType, outputStream);
}
/**
* 图片添加文字水印
*
* @param sourcePath
* @param targetPath
* @param font
* @param color
* @param x
* @param y
* @param watermarkText
* @throws IOException
*/
public static void watermarkText(String sourcePath, String targetPath, Font font, Color color, int x, int y, String watermarkText) throws IOException {
String fileType = targetPath.substring(targetPath.lastIndexOf(".") + 1);
try (FileInputStream inputStream = new FileInputStream(sourcePath);
FileOutputStream outputStream = new FileOutputStream(targetPath)) {
watermarkText(inputStream, outputStream, font, color, x, y, watermarkText, fileType);
}
}
/**
* 图片添加文字水印
*
* @param file
* @param outputStream
* @param font
* @param color
* @param x
* @param y
* @param watermarkText
* @throws IOException
*/
public static void watermarkText(MultipartFile file, OutputStream outputStream, Font font, Color color, int x, int y, String watermarkText) throws IOException {
String originalFilename = file.getOriginalFilename();
Assert.notNull(originalFilename, "文件非法");
String fileType = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
try (InputStream inputStream = file.getInputStream()) {
watermarkText(inputStream, outputStream, font, color, x, y, watermarkText, fileType);
}
}
private static void watermarkText(InputStream inputStream, OutputStream outputStream, Font font, Color color, int x, int y, String watermarkText, String fileType) throws IOException {
// 读取图片
BufferedImage image = ImageIO.read(inputStream);
Graphics2D g2d = image.createGraphics();
// 设置文字字体、样式
g2d.setFont(font);
g2d.setColor(color);
g2d.drawString(watermarkText, x, y);
g2d.dispose();
// 保存新图片
ImageIO.write(image, fileType, outputStream);
}
/**
* 图片添加图片水印
*
* @param sourcePath
* @param appendSourcePath
* @param targetPath
* @param x
* @param y
* @param width
* @param height
* @throws IOException
*/
public static void watermarkImage(String sourcePath, String appendSourcePath, String targetPath, int x, int y, int width, int height) throws IOException {
String fileType = targetPath.substring(targetPath.lastIndexOf(".") + 1);
try (FileInputStream inputStream = new FileInputStream(sourcePath);
FileInputStream appendInputStream = new FileInputStream(appendSourcePath);
FileOutputStream outputStream = new FileOutputStream(targetPath)) {
watermarkImage(inputStream, appendInputStream, outputStream, x, y, width, height, fileType);
}
}
/**
* 图片添加图片水印
*
* @param file
* @param appendFile
* @param outputStream
* @param x
* @param y
* @param width
* @param height
* @throws IOException
*/
public static void watermarkImage(MultipartFile file, MultipartFile appendFile, OutputStream outputStream, int x, int y, int width, int height) throws IOException {
String originalFilename = file.getOriginalFilename();
Assert.notNull(originalFilename, "文件非法");
String fileType = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
try (InputStream inputStream = file.getInputStream();
InputStream appendInputStream = appendFile.getInputStream()) {
watermarkImage(inputStream, appendInputStream, outputStream, x, y, width, height, fileType);
}
}
private static void watermarkImage(InputStream inputStream, InputStream appendInputStream, OutputStream outputStream, int x, int y, int width, int height, String fileType) throws IOException {
// 读取图片
BufferedImage image = ImageIO.read(inputStream);
Graphics2D g2d = image.createGraphics();
// 设置水印图片的起始x/y坐标、宽度、高度
BufferedImage appendImage = ImageIO.read(appendInputStream);
g2d.drawImage(appendImage, x, y, width, height, null, null);
g2d.dispose();
// 保存新图片
ImageIO.write(image, fileType, outputStream);
}
public static void main(String[] args) throws Exception {
ImageOperateUtil.convert("C:/Users/16/Desktop/image/mianju.jpg", "C:/Users/16/Desktop/image/mianju0.png");
ImageOperateUtil.compress("C:/Users/16/Desktop/image/mianju.jpg", "C:/Users/16/Desktop/image/mianju1.jpg", 0.3f);
ImageOperateUtil.crop("C:/Users/16/Desktop/image/mianju.jpg", "C:/Users/16/Desktop/image/mianju2.jpg", 3000, 2000);
ImageOperateUtil.crop("C:/Users/16/Desktop/image/mianju.jpg", "C:/Users/16/Desktop/image/mianju3.jpg", 500, 500, 3000, 2000);
ImageOperateUtil.reduceByRatio("C:/Users/16/Desktop/image/mianju.jpg", "C:/Users/16/Desktop/image/mianju4.jpg", 2);
ImageOperateUtil.enlargeByRatio("C:/Users/16/Desktop/image/mianju.jpg", "C:/Users/16/Desktop/image/mianju5.jpg", 2);
ImageOperateUtil.resize("C:/Users/16/Desktop/image/mianju.jpg", "C:/Users/16/Desktop/image/mianju6.jpg", 3000, 2000);
ImageOperateUtil.gray("C:/Users/16/Desktop/image/mianju.jpg", "C:/Users/16/Desktop/image/mianju7.jpg");
ImageOperateUtil.watermarkText("C:/Users/16/Desktop/image/mianju.jpg", "C:/Users/16/Desktop/image/mianju8.jpg",
new Font("宋体", Font.BOLD, 150), new Color(255, 255, 255, 255), 300, 500, "哈哈哈哈");
ImageOperateUtil.watermarkImage("C:/Users/16/Desktop/image/mianju.jpg", "C:/Users/16/Desktop/image/demo.jpeg",
"C:/Users/16/Desktop/image/mianju9.jpg", 0, 0, 500, 500);
}
}
接口调用
package com.qiangesoft.image.controller;
import com.qiangesoft.image.utils.ImageOperateUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
/**
* 测试
*
* @author qiangesoft
* @date 2024-04-26
*/
@RequestMapping("/image")
@RestController
public class ImageController {
@GetMapping("/convert")
public void convert(@RequestPart MultipartFile file, HttpServletResponse response) throws IOException {
settingResponse(response, "图片格式转换.png");
try (ServletOutputStream outputStream = response.getOutputStream()) {
ImageOperateUtil.convert(file, outputStream, "png");
}
}
@GetMapping("/compress")
public void compress(@RequestPart MultipartFile file, HttpServletResponse response) throws IOException {
settingResponse(response, "图片压缩.png");
try (ServletOutputStream outputStream = response.getOutputStream()) {
ImageOperateUtil.compress(file, outputStream, 0.4f);
}
}
@GetMapping("/crop")
public void crop(@RequestPart MultipartFile file, HttpServletResponse response) throws IOException {
settingResponse(response, "图片裁剪.png");
try (ServletOutputStream outputStream = response.getOutputStream()) {
ImageOperateUtil.crop(file, outputStream, 500, 400);
}
}
@GetMapping("/reduceByRatio")
public void reduceByRatio(@RequestPart MultipartFile file, HttpServletResponse response) throws IOException {
settingResponse(response, "图片比例缩小.png");
try (ServletOutputStream outputStream = response.getOutputStream()) {
ImageOperateUtil.reduceByRatio(file, outputStream, 3);
}
}
@GetMapping("/enlargeByRatio")
public void enlargeByRatio(@RequestPart MultipartFile file, HttpServletResponse response) throws IOException {
settingResponse(response, "图片比例放大.png");
try (ServletOutputStream outputStream = response.getOutputStream()) {
ImageOperateUtil.enlargeByRatio(file, outputStream, 2);
}
}
@GetMapping("/resize")
public void resize(@RequestPart MultipartFile file, HttpServletResponse response) throws IOException {
settingResponse(response, "图片宽高重置.png");
try (ServletOutputStream outputStream = response.getOutputStream()) {
ImageOperateUtil.resize(file, outputStream, 1000, 500);
}
}
@GetMapping("/gray")
public void gray(@RequestPart MultipartFile file, HttpServletResponse response) throws IOException {
settingResponse(response, "图片灰化.png");
try (ServletOutputStream outputStream = response.getOutputStream()) {
ImageOperateUtil.gray(file, outputStream);
}
}
@GetMapping("/watermarkText")
public void watermarkText(@RequestPart MultipartFile file, HttpServletResponse response) throws IOException {
settingResponse(response, "图片文字水印.png");
try (ServletOutputStream outputStream = response.getOutputStream()) {
ImageOperateUtil.watermarkText(file, outputStream, new Font("宋体", Font.BOLD, 150),
new Color(255, 255, 255, 255), 300, 500, "哈哈哈哈");
}
}
@GetMapping("/watermarkImage")
public void watermarkImage(@RequestPart MultipartFile file, @RequestPart MultipartFile appendFile, HttpServletResponse response) throws IOException {
settingResponse(response, "图片图片水印.png");
try (ServletOutputStream outputStream = response.getOutputStream()) {
ImageOperateUtil.watermarkImage(file, appendFile, outputStream, 0, 0, 300, 500);
}
}
private static void settingResponse(HttpServletResponse response, String fileName) {
response.setCharacterEncoding("utf-8");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
}
}