一.效果展示
水印前 水印后
二.代码实现
/**
* 在给定的图片上添加文本水印。
*
* @param sourceImgPath 源图片路径
* @param waterMarkContent 水印内容,多个内容用逗号分隔
* @param degreeAngle 设置水印文字的旋转角度,默认为 -45 度
* @param transparency 设置水印透明度,默认为 1.0(不透明)
* @return 添加了水印的 BufferedImage 对象
*/
public static BufferedImage addWaterMark(String sourceImgPath,
String waterMarkContent,
Integer degreeAngle,
float transparency) {
long startTime = System.currentTimeMillis();
// 初始化变量
BufferedImage bufImg = null;
Font font = new Font("宋体", Font.BOLD, 12); // 水印字体、大小
Color markContentColor = Color.white; // 水印颜色
Integer degree = degreeAngle; // 设置水印文字的旋转角度
float alpha = transparency; // 设置水印透明度
try {
// 读取源图片文件并转换为 Image 对象
File srcImgFile = new File(sourceImgPath);
Image srcImg = ImageIO.read(srcImgFile);
// 获取图片的宽度和高度
int srcImgWidth = srcImg.getWidth(null);
int srcImgHeight = srcImg.getHeight(null);
// 创建 BufferedImage 对象,用于绘制水印
bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bufImg.createGraphics();
// 将原始图片绘制到 BufferedImage 中
g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
// 设置水印颜色和字体
g.setColor(markContentColor);
g.setFont(font);
// 设置水印透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
// 如果设置了旋转角度,则进行文字旋转
if (null != degree) {
g.rotate(Math.toRadians(degree), (double) bufImg.getWidth(), (double) bufImg.getHeight());
}
// 按逗号分隔水印内容
String[] split = waterMarkContent.split(",");
int i = 0;
// 遍历每个水印内容并绘制到图片上
for (String s : split) {
// 计算文字的宽度和高度
FontMetrics fontMetrics = g.getFontMetrics();
int textWidth = fontMetrics.stringWidth(s);
int textHeight = fontMetrics.getHeight();
// 计算文字的位置,放在右下角留一些边距
int x = srcImgWidth - textWidth - 10; // 10 是右边距
int y = srcImgHeight - textHeight - 10 * split.length + textHeight * i; //下边距
i++;
// 绘制水印文字
g.drawString(s, x, y);
}
// 释放资源
g.dispose();
// 记录方法执行结束时间并输出日志
long endTime = System.currentTimeMillis();
log.info("文本内容水印生成图片...完成,耗时 " + (endTime - startTime) + " ms");
} catch (Exception e) {
e.printStackTrace();
e.getMessage();
}
// 返回添加了水印的 BufferedImage 对象
return bufImg;
}
这段代码是一个Java方法,用于在给定的图片上添加文本水印。让我来解释一下这段代码的主要功能和一些需要注意的地方:
-
方法签名和参数说明:
addWaterMark
方法接收四个参数:sourceImgPath
(源图片路径)、waterMarkContent
(水印内容)、degreeAngle
(旋转角度)、transparency
(透明度)。degreeAngle
和transparency
是可选参数,分别用于设置水印文字的旋转角度和透明度。
-
方法实现:
- 首先,方法开始时记录了当前时间,用于计算方法执行时间。
- 创建了一个
BufferedImage
对象bufImg
,作为最终生成带水印的图片。 - 使用
ImageIO.read
从指定路径读取源图片并转换为Image
对象。 - 获取源图片的宽度和高度。
- 创建
Graphics2D
对象g
,并将源图片绘制到bufImg
中。 - 设置水印文字的颜色、字体和透明度。
- 如果提供了
degreeAngle
,则设置水印文字的旋转角度。 - 将
waterMarkContent
按逗号分隔(这里是以逗号分隔)。 - 遍历分隔后的水印内容,计算每段文字的宽度和高度,并确定其位置(右下角留有一定的边距)。
- 使用
drawString
方法将每段水印文字绘制到图片上。 - 释放
Graphics2D
资源,记录方法执行结束时间,并输出日志。
-
返回值:
- 返回生成的带水印的
BufferedImage
对象bufImg
。
- 返回生成的带水印的
三.测试类
/**
*
* @Description: 图片水印测试类
* @User: xxx
* @Date: 2024/8/6
*/
public class ImageWaterMarkTest {
public static void main(String[] args) throws Exception {
//原图本地路径、保存图的本地路径
String sourcePath = "C:\\Users\\zy011\\Desktop\\图片\\Snipaste_2024-05-29_13-53-10.png";
String targetPath = "C:\\Users\\zy011\\Desktop\\图片\\Snipaste_2024-05-29_13-53-10_Test.png";
//透明度
float alpha = 1.0f;
//图片类型
String IMAGE_TYPE_JPG = "jpg";
//图片生成水印
BufferedImage mcdonaldTestImage = ImageWaterMarkUtil.addWaterMark(sourcePath,
"某某科技有限公司,张三丰,2024年8月6日", //水印每行用 ,号隔开
null, alpha);
//图片无损再次保存 (工具类在下方)
ImageLossLessUtil.saveLossLessImage(mcdonaldTestImage, targetPath, IMAGE_TYPE_JPG);
}
}
附图片无损保存工具
/**
* Description 无损操作图片
* ProjectName imagetool
* Version 1.0
*/
public class ImageLossLessUtil {
/**
* @Description 把图片无损再次保存
* @Date 2022/4/18 13:48
* @param sourceImgPath - 原始文件路径
* @param targetImgPath - 目标文件路径
* @param suffix - 文件格式
* @return void
**/
public static void saveLossLessImage(String sourceImgPath,String targetImgPath,String suffix) throws Exception{
BufferedImage image = ImageIO.read(new File(sourceImgPath));
saveLossLessImage(image,targetImgPath,suffix);
}
/**
* @Description 把图片无损再次保存
* @Date 2022/4/18 13:48
* @param image - BufferedImage对象
* @param targetImgPath - 目标文件路径
* @param suffix - 文件格式
* @return void
**/
public static void saveLossLessImage(BufferedImage image,String targetImgPath,String suffix) throws Exception{
//不压缩图片质量进行保存
ImageWriter writer = ImageIO.getImageWritersBySuffix(suffix).next();
ImageWriteParam imageWriteParam = writer.getDefaultWriteParam();
imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
//0-1范围 越大质量越高
imageWriteParam.setCompressionQuality(1);
ByteArrayOutputStream output = new ByteArrayOutputStream();
writer.setOutput(new MemoryCacheImageOutputStream(output));
writer.write(null,new IIOImage(image,null,null),imageWriteParam);
writer.dispose();
//最终图片保存路径
FileOutputStream file = new FileOutputStream(targetImgPath);
file.write(output.toByteArray());
file.close();
output.close();
}
}
好,以上就是全部内容,能坚持看到这里,你一定很有收获,那么动一动拿offer的小手,点个赞再走吧,听说这么做的人2024年都交了好运!!!