图片加水印功能的实现
最近公司需要实现一个图片加水印的功能。
简单看了下需求,因为之前做截图工具的时候,对图片处理稍微做了一些理解,于是就简单的实现了一个为图片加水印的工具类。
先看效果:
-
原图
原图 -
水印图
加水印后
源代码
import lombok.Setter;
import lombok.SneakyThrows;
import lombok.experimental.Accessors;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 图像加水印工具类
*
* @author HanQi [Jpanda@aliyun.com]
* @version 1.0
* @since 2020/3/17 9:44
*/
@Accessors(chain = true, fluent = true)
public class ImageMaskHelper {
private BufferedImage bi;
private Graphics2D g2;
private OutputStream out;
/**
* 文字颜色
*/
@Setter
private Color color = Color.WHITE;
/**
* 文字字体
*/
@Setter
private Font font = new Font("simhei", Font.BOLD, 30);
/**
* 水印间距
*/
@Setter
private Integer interval = 160;
/**
* 旋转度数
*/
@Setter
private Integer rotate = 45;
/**
* 图片类型
*/
@Setter
private String imageType = "JPEG";
/**
* 允许定制Graphics2D
*/
@Setter
private Composite composite = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.3F);
@SneakyThrows
private ImageMaskHelper(InputStream image) {
this.bi = ImageIO.read(image);
this.g2 = bi.createGraphics();
}
public static ImageMaskHelper of(InputStream image) {
return new ImageMaskHelper(image);
}
public ImageMaskHelper to(OutputStream outputStream) {
this.out = outputStream;
return this;
}
@SneakyThrows
public void doMask(String mask) {
// 文字旋转
g2.setColor(color);
AffineTransform affineTransform = new AffineTransform();
affineTransform.rotate(Math.toRadians(rotate), 0, 0);
g2.setFont(font.deriveFont(affineTransform));
g2.setComposite(composite);
// 文字宽度
int fw = g2.getFontMetrics().stringWidth(mask);
// 文本高度
int fh = g2.getFontMetrics().getHeight();
// 计算增量
int xInc = fw + interval;
int yInc = fh + interval;
// 添加水印
int y = 0;
do {
int x = 0;
do {
g2.drawString(mask, x, y);
x += xInc;
} while (x < bi.getWidth());
y += yInc;
} while (y < bi.getHeight());
g2.dispose();
if (this.out != null) {
ImageIO.write(bi, imageType, out);
}
}
}
测试代码
// IMAGE 原图
// MASK_IMAGE 加水印后的图片文件
@Test
@SneakyThrows
public void doMask() {
@Cleanup
FileInputStream fileInputStream = FileUtils.openInputStream(Paths.get(IMAGE).toFile());
@Cleanup
FileOutputStream fileOutputStream = new FileOutputStream(Paths.get(MASK_IMAGE).toFile());
ImageMaskHelper
.of(fileInputStream)
.to(fileOutputStream)
.color(Color.BLACK)
.interval(180)
.rotate(330)
.imageType("png")
.doMask("Jpanda.cn");
fileOutputStream.flush();
}
网友评论