@Resource
private ActionManageConfig actionManageConfig;
private ArrayList<WatermarkFrame> fullScreenWatermarks = new ArrayList<>();
@Value("${work-unit.watermark.text}")
private String defaultWatermarkText;
@Value("${work-unit.watermark.color}")
private String defaultColor;
/**
* 初始屏幕水印
*/
@PostConstruct
public void watermark() {
ClientInfo baseInfo = baseService.getBaseInfo();
HashMap<String, Object> map = new HashMap<String, Object>() {{
put("clientId", baseInfo.getClientId());
}};
String jsonString = null;
try {
jsonString = HttpUtil.get(actionManageConfig.getIp() + ":" + actionManageConfig.getPort() + "/watermark/getByClientId", map);
} catch (Exception e) {
return;
}
JSONObject jsonObject = new JSONObject(jsonString);
JSONObject object = jsonObject.getJSONObject("data");
if (object != null) {
String fontType = object.getStr("fontType");
String color = object.getStr("color");
String watermarkText = object.getStr("watermarkText");
Integer offset = object.getInt("offset");
Integer angle = object.getInt("angle");
Integer fontSize = object.getInt("fontSize");
// 1、获取所有屏幕设备
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] screens = ge.getScreenDevices();
// 遍历每个屏幕设备并创建全屏水印窗口
fullScreenWatermarks.clear();
for (GraphicsDevice screen : screens) {
fullScreenWatermarks.add(new WatermarkFrame(screen, watermarkText, angle, fontSize, fontType, color, offset));
}
} else {
String fontType = "黑体";
String color = defaultColor;
String watermarkText = defaultWatermarkText;
Integer offset = 200;
Integer angle = 30;
Integer fontSize = 36;
// 1、获取所有屏幕设备
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] screens = ge.getScreenDevices();
// 遍历每个屏幕设备并创建全屏水印窗口
fullScreenWatermarks.clear();
for (GraphicsDevice screen : screens) {
fullScreenWatermarks.add(new WatermarkFrame(screen, watermarkText, angle, fontSize, fontType, color, offset));
}
}
import com.sun.jna.Native;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinUser;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.geom.AffineTransform;
public class WatermarkFrame extends Frame {
private static final int WHITE_COLOR_KEY = 0xFF0000; // White color RGB value
private String watermarkText;
private Integer angle;
private Integer fontSize;
private String fontType;
private String color;
private Integer offset;
private Rectangle screenBounds;
public WatermarkFrame(GraphicsDevice screen, String watermarkText, Integer angle, Integer fontSize, String fontType, String color, Integer offset) {
this.angle = angle;
this.fontSize = fontSize;
this.fontType = fontType;
this.color = color;
this.watermarkText = watermarkText;
this.offset = offset;
setUndecorated(true); // 无边框
setAlwaysOnTop(true); // 始终在最前面
setType(Window.Type.UTILITY); // 不在任务栏展示窗口
// 获取屏幕的大小
screenBounds = screen.getDefaultConfiguration().getBounds();
setSize(screenBounds.width, screenBounds.height); // 设置窗口宽高
setLocation(screenBounds.x, screenBounds.y);// 将窗口定位到屏幕的左上角
setBackground(new Color(0, 0, 0, 0)); // 白色透明背景,最后一个参数是透明度
// 添加窗口事件
addComponentListener(new ComponentAdapter() {
// 窗口展示后触发事件
@Override
public void componentShown(ComponentEvent e) {
// 为窗口透传鼠标交互事件,用的是JNI调用 Windows 的API
makeClickThrough(WatermarkFrame.this);
}
});
// 设置窗口可见
setVisible(true);
}
@Override
public void paint(Graphics gra) {
super.paint(gra);
Graphics2D g2d = (Graphics2D) gra;
// 设置水印文本属性
Font watermarkFont = new Font(fontType, Font.PLAIN, fontSize);
g2d.setFont(watermarkFont);
int r = Integer.parseInt(color.substring(0, 2), 16);
int g = Integer.parseInt(color.substring(2, 4), 16);
int b = Integer.parseInt(color.substring(4, 6), 16);
g2d.setColor(new Color(r, g, b, 100));
// 计算水印文本的宽度和高度
FontMetrics fontMetrics = g2d.getFontMetrics();
int textWidth = fontMetrics.stringWidth(watermarkText);
int textHeight = fontMetrics.getHeight();
// 设置水印倾斜角度
double shearAngle = Math.toRadians(-angle); // 设置倾斜角度为30度
// 计算水印在屏幕上的均匀分布位置
int offsetX = offset; // 水印之间的水平间距
int offsetY = offset; // 水印之间的垂直间距
int rows = screenBounds.height / offsetY;
int cols = screenBounds.width / offsetX;
// 绘制水印
for (int row = 0; row <= rows; row++) {
for (int col = 0; col <= cols; col++) {
int x = col * offsetX;
int y = row * offsetY;
// 创建 AffineTransform 对象,用于设置倾斜
AffineTransform orig = g2d.getTransform();
AffineTransform at = new AffineTransform();
at.setToRotation(shearAngle, x, y);
g2d.setTransform(at);
g2d.drawString(watermarkText, x, y);
// 恢复原始的 AffineTransform
g2d.setTransform(orig);
}
}
}
public static void makeClickThrough(Window window) {
WinDef.HWND hwnd = new WinDef.HWND(Native.getWindowPointer(window));
User32.INSTANCE.SetWindowLong(hwnd, WinUser.GWL_EXSTYLE,
User32.INSTANCE.GetWindowLong(hwnd, WinUser.GWL_EXSTYLE) | WinUser.WS_EX_LAYERED | WinUser.WS_EX_TRANSPARENT);
// 这段 WinUser.LWA_COLORKEY 代表指定颜色透明、WHITE_COLOR_KEY 就是前面定义的白色、 0 就是透明度,表示完全透明
User32.INSTANCE.SetLayeredWindowAttributes(hwnd, WHITE_COLOR_KEY, (byte) 0, WinUser.LWA_COLORKEY);
}
}