斜水印工具类

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.io.OutputStream;


public class ImageWatermarkUtil {
    /**
     * 水印之间的横向间隔
     */
    private static final int X_MOVE = 200;

    /**
     * 水印之间的纵向间隔
     */
    private static final int Y_MOVE = 200;


    /**
     * 给图片添加文字水印
     *
     * @param markerText   水印文字内容
     * @param inputStream  图片输入流
     * @param outputStream 图片输出流
     */
    public static void markerText(String markerText, InputStream inputStream, OutputStream outputStream) {
        int fontSize = 36;
        Color color = Color.GRAY;
        float alpha = 0.5f;

        try {
            Font font = new Font("SansSerif", Font.BOLD, fontSize);
            // 获取文字水印的大小
            int maxLen = getStringLength(font, markerText);
            int maxHigh = fontSize + 10; // 单行文字高度

            BufferedImage srcImg = ImageIO.read(inputStream);//文件转化为图片
            int srcImgWidth = srcImg.getWidth(null);//获取图片的宽
            int srcImgHeight = srcImg.getHeight(null);//获取图片的高
            // 加水印
            Graphics2D g = srcImg.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), (double) srcImgWidth / 2, (double) srcImgHeight / 2);//设置水印旋转

            // 旋转45度后需要更大的覆盖范围
            //一个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;
                int y = 40 + 10 + t;
                // 文字叠加位置
                int tempX = -(int) (srcImgWidth * 0.7);
                int tempY = -(int) (srcImgHeight * 0.7) + y + yz;
                // 单字符长度
                int tempCharLen = 0;
                // 单行字符总长度临时计算
                int tempLineLen = 0;
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < markerText.length(); i++) {
                    char tempChar = markerText.charAt(i);
                    tempCharLen = g.getFontMetrics(g.getFont()).charWidth(tempChar);
                    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 + X_MOVE;
                }
                yz = yz + maxHigh + Y_MOVE;
            }
            g.dispose();// 释放资源
            ImageIO.write(srcImg, "JPEG", outputStream);// 输出流
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取文字水印的宽
     *
     * @param font
     * @param markContent
     * @return
     */
    public static int getStringLength(Font font, String markContent) {
        if (markContent == null || markContent.isEmpty()) {
            return 0;
        }
        if (null == font) {
            font = new Font(null);
        }
        JLabel label = new JLabel(markContent);
        FontMetrics metrics = label.getFontMetrics(font);
        //文字水印的宽
        return metrics.stringWidth(label.getText());
    }
}
posted @ 2025-04-09 16:19  菜鸡互啄_ye  阅读(26)  评论(0)    收藏  举报