封装在如下工具类中
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.exin.rhaj.common.enums.Position;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* 图片工具类
*
* @author yxm
*/
public abstract class ImageUtil {
/**
* 拉伸图片尺寸
*
* @param originalImage 源图片对象
* @param newWidth 目标宽度 像素
* @param newHeight 目标高度 像素
* @return
* @throws IOException
*/
public static BufferedImage stretch(BufferedImage originalImage, int newWidth, int newHeight) throws IOException {
if (originalImage == null) {
throw new NullPointerException("图片文件不能为空");
}
if (newWidth < 100 || newHeight < 100) {
throw new IllegalArgumentException("图片宽和高不能小于100像素");
}
// 创建目标图像
BufferedImage targetImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
// 创建画笔
Graphics2D g2d = targetImage.createGraphics();
// 设置拉伸模式为双线性插值算法
RenderingHints hints = new RenderingHints(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHints(hints);
// 绘制拉伸后的图像
g2d.drawImage(originalImage, 0, 0, newWidth, newHeight, null);
g2d.dispose();
return targetImage;
}
/**
* 拉伸图片尺寸
*
* @param imageStream 源图片文件流
* @param newWidth 目标宽度 像素
* @param newHeight 目标高度 像素
* @return
* @throws IOException
*/
public static BufferedImage stretch(InputStream imageStream, int newWidth, int newHeight) throws IOException {
BufferedImage originalImage = ImageIO.read(imageStream);
return stretch(originalImage, newWidth, newHeight);
}
/**
* 拉伸图片尺寸
*
* @param imageFile 源图片文件
* @param newWidth 目标宽度 像素
* @param newHeight 目标高度 像素
* @return
* @throws IOException
*/
public static BufferedImage stretch(File imageFile, int newWidth, int newHeight) throws IOException {
return stretch(new FileInputStream(imageFile), newWidth, newHeight);
}
/**
* 拉伸图片尺寸
*
* @param imagePath 源图片文件路径
* @param newWidth 目标宽度 像素
* @param newHeight 目标高度 像素
* @return
* @throws IOException
*/
public static BufferedImage stretch(String imagePath, int newWidth, int newHeight) throws IOException {
return stretch(new File(imagePath), newWidth, newHeight);
}
/**
* 选定一个位置打上水印
*
* @param originalImage 源图片对象
* @param content 水印内容
* @param positions 水印位置 枚举
* @return
* @throws IOException
*/
public static BufferedImage watermark(BufferedImage originalImage, String content, Position[] positions) throws IOException {
if (originalImage == null) {
throw new NullPointerException("图片文件不能为空");
}
if (StrUtil.isBlank(content)) {
throw new IllegalArgumentException("水印内容不能为空");
}
if (ArrayUtil.isEmpty(positions)) {
throw new IllegalArgumentException("水印位置至少要包含一个");
}
// 获取源图片宽高
int imageWidth = originalImage.getWidth();
int imageHeight = originalImage.getHeight();
// 合理计算出水印的尺寸 注:坐标为文字的左下角
int fontSize = (imageWidth + imageHeight) / 40;
int fontWidth = fontSize * content.length();
int fontHeight = fontSize;
// 水印坐标为
int positionLeft = 0;
int positionTop = 0;
// 创建目标图像
BufferedImage targetImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
// 创建画笔
Graphics2D g2d = targetImage.createGraphics();
// 绘制源图像在目标图像上
g2d.drawImage(originalImage, 0, 0, imageWidth, imageHeight, null);
// 设置水印颜色
g2d.setColor(new Color(255, 255, 255, 128));
// 设置水印字体、大小 画笔字体样式,加粗,文字大小
g2d.setFont(new Font("微软雅黑", Font.BOLD, fontSize));
//设置 alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.9f));
for (Position position : positions) {
// 根据位置计算水印坐标
switch (position) {
case TOP:
positionLeft = imageWidth / 2 - fontWidth / 2;
positionTop = fontHeight;
break;
case TOP_RIGHT:
positionLeft = imageWidth - fontWidth;
positionTop = 0 + fontHeight;
break;
case RIGHT:
positionLeft = imageWidth - fontWidth;
positionTop = imageHeight / 2 - fontHeight / 2;
break;
case RIGHT_BOTTOM:
positionLeft = imageWidth - fontWidth;
positionTop = imageHeight;
break;
case BOTTOM:
positionLeft = imageWidth / 2 - fontWidth / 2;
positionTop = imageHeight;
break;
case BOTTOM_LEFT:
positionLeft = 0;
positionTop = imageHeight;
break;
case LEFT:
positionLeft = 0;
positionTop = imageHeight / 2 + fontHeight / 2;
break;
case LEFT_TOP:
positionLeft = 0;
positionTop = fontHeight;
break;
default:
break;
}
// 绘制水印
g2d.drawString(content, positionLeft, positionTop);
}
g2d.dispose();
return originalImage;
}
/**
* 选定一个位置打上水印
*
* @param imageStream 图片源文件流
* @param content 水印内容
* @param positions 水印位置 枚举
* @return
* @throws IOException
*/
public static BufferedImage watermark(InputStream imageStream, String content, Position[] positions) throws IOException {
BufferedImage originalImage = ImageIO.read(imageStream);
return watermark(originalImage, content, positions);
}
/**
* 选定一个位置打上水印
*
* @param imageFile 图片源文件
* @param content 水印内容
* @param positions 水印位置 枚举
* @return
* @throws IOException
*/
public static BufferedImage watermark(File imageFile, String content, Position[] positions) throws IOException {
return watermark(new FileInputStream(imageFile), content, positions);
}
/**
* 选定位置(多选)打上水印
*
* @param imagePath 图片源文件路径
* @param content 水印内容
* @param positions 水印位置 枚举
* @return
* @throws IOException
*/
public static BufferedImage watermark(String imagePath, String content, Position[] positions) throws IOException {
return watermark(new File(imagePath), content, positions);
}
/**
* 保存图片至指定路径(包含文件名)
*
* @param imageFile 源图片
* @param outPath 保存路径
* @param formatName 源图片后缀名
* @throws IOException
*/
public static boolean save(BufferedImage imageFile, String outPath, String formatName) throws IOException {
return ImageIO.write(imageFile, formatName, new File(outPath));
}
/**
* 保存图片至指定路径(包含文件名)
*
* @param imageFile 源图片
* @param outFillPath 保存路径
* @return
* @throws IOException
*/
public static boolean save(BufferedImage imageFile, String outFillPath) throws IOException {
String imageType = outFillPath.substring(outFillPath.indexOf(".", -1) + 1);
return ImageIO.write(imageFile, imageType, new File(outFillPath));
}
}