java对整张图片添加水印
- 把水印铺满整张图片
参考代码
java
private final static Map<String,Object> imageConfig = getImgDefaultConfig();
public static Map<String,Object> getImgDefaultConfig(){
Map<String, Object> config = new HashMap<>();
config.put("alpha",0.5f); // 水印透明度
config.put("fontSize",28); // 水印文字大小
config.put("font",new Font("微软雅黑", Font.PLAIN, 28)); // 水印文字字体
config.put("color",Color.gray); // 水印文字颜色
config.put("xMove",80); // 水印之间的间隔
config.put("yMove",80); // 水印之间的间隔
config.put("degree",-40);// 旋转角度
config.put("formatName","JPG");
return config;
}
/**
* 获取文本长度。汉字为1:1,英文和数字为2:1
*/
private static int getTextLength(String text) {
int length = text.length();
for (int i = 0; i < text.length(); i++) {
String s = String.valueOf(text.charAt(i));
if (s.getBytes().length > 1) {
length++;
}
}
length = length % 2 == 0 ? length / 2 : length / 2 + 1;
return length;
}
/**
* 给图片添加水印文字、可设置水印文字的旋转角度
* @param logoText 水印文字
* @param inputStream
* @param outputStream
*/
public static void imageByText(String logoText, InputStream inputStream, OutputStream outputStream, Map<String, Object> config) throws IOException {
// 源图片
Image srcImg = ImageIO.read(inputStream);
// 原图宽度
int width = srcImg.getWidth(null);
// 原图高度
int height = srcImg.getHeight(null);
BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null), srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
// 构建画笔对象
Graphics2D g = buffImg.createGraphics();
try {
// 设置对线段的锯齿状边缘处理
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0, null);
// 设置水印旋转
Integer degree = (Integer) config.getOrDefault("degree", imageConfig.get("degree"));
if (null != degree) {
g.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);
}
// 设置水印文字颜色
g.setColor((Color) config.getOrDefault("color", imageConfig.get("color")));
// 设置水印文字Font
g.setFont((Font) config.getOrDefault("font", imageConfig.get("font")));
// 设置水印文字透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, (Float) config.getOrDefault("alpha", imageConfig.get("alpha"))));
int x = -width / 2;
int y;
// 字体高度
int markHeight = (int) config.getOrDefault("fontSize", imageConfig.get("fontSize"));
// 字体长度
int markWidth = markHeight * getTextLength(logoText);
// 循环添加水印
while (x < width * 1.5) {
y = -height / 2;
while (y < height * 1.5) {
g.drawString(logoText, x, y);
y += markHeight + (int) config.getOrDefault("yMove", imageConfig.get("yMove"));
}
x += markWidth + (int) config.getOrDefault("xMove", imageConfig.get("xMove"));
}
} finally {
// 释放资源
g.dispose();
}
// 生成图片
ImageIO.write(buffImg, (String) config.getOrDefault("formatName", imageConfig.get("formatName")), outputStream);
}
测试
java
public static void main(String[] args) throws IOException {
String logoText = "测试水印-abments";
imageByText(logoText, new FileInputStream("F:\\tmp\\1\\test.jpg"), new FileOutputStream("F:\\tmp\\1\\test-水印.jpg"), new HashMap<>());
}
效果展示
说明
方法imageByText的参数设置为InputStream inputStream, OutputStream outputStream,是为了方便java中直接输出给响应体对象。
在使用过程如果遇到问题欢迎留言讨论。