|
|
|
@ -0,0 +1,184 @@
|
|
|
|
|
package com.supervision.utils;
|
|
|
|
|
|
|
|
|
|
import com.itextpdf.text.DocumentException;
|
|
|
|
|
import com.itextpdf.text.Element;
|
|
|
|
|
import com.itextpdf.text.pdf.*;
|
|
|
|
|
|
|
|
|
|
import javax.imageio.ImageIO;
|
|
|
|
|
import javax.swing.*;
|
|
|
|
|
import java.awt.*;
|
|
|
|
|
import java.awt.image.BufferedImage;
|
|
|
|
|
import java.io.*;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
public class WatermarkUtil {
|
|
|
|
|
|
|
|
|
|
private final static Map<String,Object> imageConfig = getImgDefaultConfig();
|
|
|
|
|
|
|
|
|
|
private final static Map<String,Object> pdfConfig = getPdfDefaultConfig();
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static Map<String,Object> getPdfDefaultConfig(){
|
|
|
|
|
Map<String, Object> config = new HashMap<>();
|
|
|
|
|
try {
|
|
|
|
|
config.put("baseFont",BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED));
|
|
|
|
|
} catch ( IOException|DocumentException e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
}
|
|
|
|
|
config.put("fillOpacity",0.3f);// 填充透明度
|
|
|
|
|
config.put("strokeOpacity",0.4f);// 笔划不透明度
|
|
|
|
|
config.put("fontSize",16);//字体大小
|
|
|
|
|
config.put("interval",-15);// 水印间隔
|
|
|
|
|
config.put("rotation",30);// 旋转角度
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void pdfByText(InputStream inputStream, OutputStream outputStream, String waterMarkName,Map<String,Object> config) throws DocumentException, IOException {
|
|
|
|
|
PdfReader reader = new PdfReader(inputStream);
|
|
|
|
|
PdfStamper stamper = new PdfStamper(reader, outputStream);
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
|
|
BaseFont base = (BaseFont) config.getOrDefault("baseFont",pdfConfig.get("baseFont"));
|
|
|
|
|
|
|
|
|
|
com.itextpdf.text.Rectangle pageRect;
|
|
|
|
|
PdfGState gs = new PdfGState();
|
|
|
|
|
gs.setFillOpacity((Float) config.getOrDefault("fillOpacity",pdfConfig.get("fillOpacity")));
|
|
|
|
|
gs.setStrokeOpacity((Float) config.getOrDefault("strokeOpacity",pdfConfig.get("strokeOpacity")));
|
|
|
|
|
int total = reader.getNumberOfPages() + 1;
|
|
|
|
|
|
|
|
|
|
JLabel label = new JLabel();
|
|
|
|
|
FontMetrics metrics;
|
|
|
|
|
int textH;
|
|
|
|
|
int textW;
|
|
|
|
|
label.setText(waterMarkName);
|
|
|
|
|
metrics = label.getFontMetrics(label.getFont());
|
|
|
|
|
textH = metrics.getHeight();
|
|
|
|
|
textW = metrics.stringWidth(label.getText());
|
|
|
|
|
|
|
|
|
|
PdfContentByte under;
|
|
|
|
|
int interval = (int) config.getOrDefault("interval", pdfConfig.get("interval"));
|
|
|
|
|
int rotation = (int) config.getOrDefault("rotation", pdfConfig.get("rotation"));
|
|
|
|
|
int fontSize = (int) config.getOrDefault("fontSize", pdfConfig.get("fontSize"));
|
|
|
|
|
for (int i = 1; i < total; i++) {
|
|
|
|
|
pageRect = reader.getPageSizeWithRotation(i);
|
|
|
|
|
under = stamper.getOverContent(i);
|
|
|
|
|
under.saveState();
|
|
|
|
|
under.setGState(gs);
|
|
|
|
|
under.beginText();
|
|
|
|
|
under.setFontAndSize(base, fontSize);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int height = interval + textH; height < pageRect.getHeight(); height = height + textH * 3) {
|
|
|
|
|
for (int width = interval + textW; width < pageRect.getWidth() + textW; width = width + textW * 2) {
|
|
|
|
|
under.showTextAligned(Element.ALIGN_LEFT
|
|
|
|
|
, waterMarkName, width - textW, height - textH, rotation);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 添加水印文字
|
|
|
|
|
under.endText();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
stamper.close();
|
|
|
|
|
reader.close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 给图片添加水印文字、可设置水印文字的旋转角度
|
|
|
|
|
* @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);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|