类似这样的。
你好,可以这样实现:
-
创建自定义主题 :: Jmix 文档 ,由于是修改
body
元素的样式,所以需要在styles.scss
文件中添加:.helium_ext { @include addons; @include helium_ext; } /*添加下列代码*/ body::after { content: ''; background-image: var(--watermark); background-repeat: repeat; background-position: 0 0, 118px 70px; position: fixed; left: 0; top: 0; width: 100%; height: 100%; pointer-events: none; z-index: 99; }
SCSS中使用了变量
--watermark
,用于后续在Java中设置不同的水印文本。如果水印文本不变。那么直接将水印图片设置到background-image
,不需要后续步骤了。
如果是动态文本水印,例如,显示登录用户的登录名,那么请继续看下面的代码:
-
在用户登录后,Jmix 会打开
MainScreen
界面,因此,我们可以在该界面的AfterShow
中添加设置水印的代码:@Subscribe public void onAfterShow(AfterShowEvent event) { // 在 AfterShow 中设置水印 setWaterMark(); screenTools.openDefaultScreen( UiControllerUtils.getScreenContext(this).getScreens()); screenTools.handleRedirect(); }
-
下面是一些工具方法,关键地方有注释,可以根据你的实际需要更改:
// 设置 body::after 中的 --watermark 变量 private void setWaterMark() { String username = currentAuthentication.getUser().getUsername(); // 修改 scss 中定义的 --watermark 变量,设置为图片的base64 UI.getCurrent().getPage().getJavaScript().execute( "var bodyStyle = document.getElementsByTagName('body')[0].style;" + "bodyStyle.setProperty('--watermark', \"url(" + getTextWatermark(username) + ")\");" ); } // 根据文字生成水印图片的 Base64 编码 private String getTextWatermark(String text) { // 这里可以修改水印图片的大小 - 也就是调整疏密度 int width = 100; int height = 100; // 创建背景透明的 BufferedImage BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D graphics = image.createGraphics(); graphics.setComposite(java.awt.AlphaComposite.Clear); graphics.fillRect(0, 0, width, height); graphics.setComposite(java.awt.AlphaComposite.Src); // 设置文字的字体、大小和颜色 graphics.setFont(new Font("Serif", Font.PLAIN, 14)); graphics.setColor(Color.LIGHT_GRAY); // 逆时针旋转角度,这里转了 π/8 AffineTransform transform = new AffineTransform(); transform.rotate(-Math.PI / 8, width / 2, height / 2); graphics.setTransform(transform); // 图片中写入文字。 int stringWidth = graphics.getFontMetrics().stringWidth(text); int x = (width - stringWidth) / 2; int y = height / 2; graphics.drawString(text, x, y); try { // 这里你可以测试一下图片输出 // ImageIO.write(image, "png", new File("output.png")); String base64 = toBase64(image); return "'data:image/png;base64," + base64 + "'"; } catch (Exception e) { return ""; } } // BufferedImage 转 base64 字符串 private static String toBase64(BufferedImage image) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(image, "png", baos); byte[] bytes = baos.toByteArray(); return Base64.getEncoder().encodeToString(bytes); }
效果如下: