图片添加水印倾斜、铺满最全工具类
可以动态修改参数调整倾斜以及字体大小、颜色等。
package com.seatrend.electronicrecord.utils; import sun.font.FontDesignMetrics; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.List; /** * @author: create by simoo * @version: v1.0 * @description: * @date:2022/9/7 */ public class ImageMarkerUtil { /** * 给图片添加文字水印 * * @param markerTextList 水印文字(一个集合一个值对应一条水印) * @param zpStrByte 源图像byte * @param response 返回流 * @param fontSize 水印字体大小 * @param color 水印的字体颜色 * @param alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字 */ public static void markerText(List<String> markerTextList, byte[] zpStrByte, HttpServletResponse response, int fontSize, Color color, float alpha) { if (zpStrByte == null) { return; } try { Font font = new Font("宋体", Font.BOLD, fontSize); String[] waterMarkContents = markerTextList.stream().toArray(String[]::new); // 获取其中最长的文字水印的大小 int maxLen = 0; int maxHigh = 0; for (int i = 0; i < waterMarkContents.length; i++) { String waterMarkContent = waterMarkContents[i]; int fontlen = getStringLength(font, waterMarkContent); if (fontlen >= maxLen) { maxLen = fontlen; } maxHigh = maxHigh + (i + 1) * fontSize + 10; } //byte转为输入流 InputStream buffin = new ByteArrayInputStream(zpStrByte, 0, zpStrByte.length); Image srcImg = ImageIO.read(buffin);//文件转化为图片 int srcImgWidth = srcImg.getWidth(null);//获取图片的宽 int srcImgHeight = srcImg.getHeight(null);//获取图片的高 // 加水印 BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB); Graphics2D g = bufImg.createGraphics();//得到画笔 g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null); g.setColor(color); //设置水印颜色 g.setFont(font);//设置字体 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));//设置水印文字透明度 g.rotate(Math.toRadians(-45), srcImgWidth, srcImgHeight);//设置水印旋转 //一个div 每行每列的打印到图片 上 int rowsNumber = srcImgHeight/maxLen+srcImgHeight%maxLen;// 图片的高 除以 文字水印的宽 打印的行数(以文字水印的宽为间隔) int columnsNumber = srcImgWidth/maxLen+srcImgWidth%maxLen;//图片的宽 除以 文字水印的宽 每行打印的列数(以文字水印的宽为间隔) //至少打印一次 if (rowsNumber < 1) { rowsNumber = 1; } if (columnsNumber < 1) { columnsNumber = 1; } int yz = 0; //遍历每行打印到图片上的个数 for (int a = 0; a < columnsNumber; a++) { int t = 0; for (int j = 0; j < waterMarkContents.length; j++) { String waterMarkContent = waterMarkContents[j]; int y = (j + 1) * 40 + 10 + t; // 文字叠加,自动换行叠加,注意符号 int tempX = -srcImgWidth / 2; int tempY = -srcImgHeight / 2 + y + yz; // 单字符长度 int tempCharLen = 0; // 单行字符总长度临时计算 int tempLineLen = 0; StringBuffer sb = new StringBuffer(); for (int i = 0; i < waterMarkContent.length(); i++) { char tempChar = waterMarkContent.charAt(i); tempCharLen = getCharLen(tempChar, g); tempLineLen += tempCharLen; // 和图片的长度进行对应的比较操作 if (tempLineLen >= srcImgWidth) { // 长度已经满一行,进行文字叠加 g.drawString(sb.toString(), tempX, tempY); t = t + 40; // 清空内容,重新追加 sb.delete(0, sb.length()); tempY += 40; tempLineLen = 0; } // 追加字符 sb.append(tempChar); } // 遍历每列打印到图片上的个数 for (int z = 0; z < rowsNumber; z++) { // 最后叠加余下的文字 g.drawString(sb.toString(), tempX, tempY); tempX = tempX + maxLen + XMOVE; } } yz = yz + maxHigh + YMOVE; } g.dispose();// 释放资源 ImageIO.write(bufImg, "JPEG", response.getOutputStream());// 输出流 } catch (Exception e) { e.printStackTrace(); e.getMessage(); } } /** * 水印之间的横向间隔 */ private static final int XMOVE = 80; /** * 水印之间的纵向间隔 */ private static final int YMOVE = 80; public static int getCharLen(char c, Graphics2D g) { return g.getFontMetrics(g.getFont()).charWidth(c); } //得到字符串长度 public static int getStringLength(Font font, String markContent) { if (StringUtils.isEmpty(markContent)) { return 0; } if (null == font) { font = new Font(null); } // FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font); // // char[] strcha = str.toCharArray(); // int strWidth = metrics.charsWidth(strcha, 0, str.length()); JLabel label = new JLabel(markContent); FontMetrics metrics = label.getFontMetrics(font); int width = metrics.stringWidth(label.getText());//文字水印的宽 return width; } }
每行水印换行借鉴博客地址(如有侵犯,立即删除):https://blog.csdn.net/weixin_46384976/article/details/126390246
调用:ImageMarkerUtil.markerText(markList, zpStrByte, response, 30, Color.gray,0.8f);
效果: