Java 图片加水印

自适应文字长度水印 

import cn.hutool.core.io.IoUtil;
import com.shinkeer.common.utils.DateUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Random;
import java.util.stream.IntStream;

/**
 * @program: 工具箱
 * @description 水印
 * @date 2023/6/6
 */
public class ImgWatermarkUtil {
    public static void main(String[] args) throws Exception {
        //imgWatermarkLocal(""D:\\公司文件\\图片.png","D:\\公司文件\\图片1.png","这是水印");
        InputStream inputStream = new FileInputStream("D:\\公司文件\\图片1.png");
        InputStream inputStreamFile = imgWatermarkInt(inputStream, "yph", "这是水印BXCVVBADSSF","png");
        saveFile(inputStreamFile,"D:\\公司文件\\图片" + DateUtils.dateTimeNow() + ".png");

    }

    public static void testFile(InputStream inputStream) throws Exception {
        InputStream inputStreamFile = imgWatermarkInt(inputStream, "这是水印", "png");
        saveFile(inputStreamFile,"D:\\公司文件\\图片" + DateUtils.dateTimeNow() + ".png");
    }

    /**
     * 保存本地
     * @param inputStream 输入流
     * @param filePath 保存地址
     * @throws IOException
     */
    public static void saveFile(InputStream inputStream, String filePath) throws IOException {
        try (OutputStream outputStream = new FileOutputStream(filePath)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        }
    }


    /**
     * 给图片添加水印
     *
     * @param inputFile     原文件路径+名称
     * @param outputFile    添加水印后输出文件保存的路径+名称
     * @param waterMarkName 添加水印的内容
     */
    public static void imgWatermarkLocal(String inputFile, String outputFile, String waterMarkName) {
        try {
            BufferedImage img = ImageIO.read(new File(inputFile));
            int width = img.getWidth();
            int height = img.getHeight();

            int fontSize = (width + height) / 80;

            Graphics2D g = img.createGraphics();
            g.setFont(new Font("黑体", Font.PLAIN, fontSize));
            g.setColor(new Color(0, 0, 0, 30));
            g.rotate(0.2);

            // 间隔
            int split = fontSize * 2;
            // 文字占用的宽度
            int xWidth = getStrWidth(waterMarkName, fontSize);
            // x,y可以绘制的数量,多加一个补充空白
            int xCanNum = width / xWidth + 1;
            int yCanNum = height / fontSize + 1;
            for (int i = 1; i <= yCanNum; i++) {
                int y = fontSize * i + split * i;
                for (int j = 0; j < xCanNum; j++) {
                    int x = xWidth * j + split * j;
                    g.drawString(waterMarkName, x, y - (fontSize + split) * j);
                }
            }
            g.dispose();
            ImageIO.write(img, "png", new File(outputFile));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 图片加水印
     *
     * @param inputStream   输入流
     * @param waterMarkName 添加水印的内容
     * @return OutputStream 输出流
     */
    public static OutputStream imgWatermarkOut(InputStream inputStream, String waterMarkName) {
        try {
            BufferedImage img = ImageIO.read(inputStream);

            int width = img.getWidth();
            int height = img.getHeight();

            int fontSize = (width + height) / 80;

            Graphics2D g = img.createGraphics();
            g.setFont(new Font("黑体", Font.PLAIN, fontSize));
            g.setColor(new Color(0, 0, 0, 30));
            g.rotate(0.2);

            // 间隔
            int split = fontSize * 2;
            // 文字占用的宽度
            int xWidth = getStrWidth(waterMarkName, fontSize);
            // x,y可以绘制的数量,多加一个补充空白
            int xCanNum = width / xWidth + 1;
            int yCanNum = height / fontSize + 1;
            for (int i = 1; i <= yCanNum; i++) {
                int y = fontSize * i + split * i;
                for (int j = 0; j < xCanNum; j++) {
                    int x = xWidth * j + split * j;
                    g.drawString(waterMarkName, x, y - (fontSize + split) * j);
                }
            }
            g.dispose();
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(img, "png", outputStream);
            return outputStream;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 图片加水印
     *
     * @param inputStream   输入流
     * @param waterMarkName 添加水印的内容
     * @param fileSuffix    扩展名
     * @return InputStream 新的输入流
     */
    public static InputStream imgWatermarkInt(InputStream inputStream, String waterMarkName, String fileSuffix) {
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            BufferedImage originalImage = ImageIO.read(inputStream);
            int width = originalImage.getWidth();
            int height = originalImage.getHeight();

            if (width <= 0 || height <= 0) {
                throw new IllegalArgumentException("Invalid image size.");
            }

            if (waterMarkName == null || waterMarkName.trim().isEmpty()) {
                throw new IllegalArgumentException("Watermark name cannot be empty.");
            }

            // 创建新的BufferedImage对象,并复制原始图像
            BufferedImage newImage = new BufferedImage(width, height, originalImage.getType());
            Graphics2D g = newImage.createGraphics();
            g.drawImage(originalImage, 0, 0, null);

            int fontSize = (width + height) / 80;
            g.setFont(new Font("黑体", Font.PLAIN, fontSize));
            g.setColor(new Color(0, 0, 0, 30));
            g.rotate(0.2);

            // 间隔
            int split = fontSize * 2;
            // 文字占用的宽度
            int xWidth = getStrWidth(waterMarkName, fontSize);
            // x,y可以绘制的数量,多加一个补充空白
            int xCanNum = width / xWidth + 1;
            int yCanNum = height / fontSize + 1;
            for (int i = 1; i <= yCanNum; i++) {
                int y = fontSize * i + split * i;
                for (int j = 0; j < xCanNum; j++) {
                    int x = xWidth * j + split * j;
                    g.drawString(waterMarkName, x, y - (fontSize + split) * j);
                }
            }
            g.dispose();

            // 将新的BufferedImage对象写入ByteArrayOutputStream中
            ImageIO.write(newImage, fileSuffix, outputStream);

            // 返回新的InputStream对象
            return new ByteArrayInputStream(outputStream.toByteArray());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 图片加水印
     *
     * @param inputStream      输入流
     * @param waterMarkNameOne 添加水印的内容
     * @param waterMarkNameTwo 添加水印的内容
     * @param fileSuffix       扩展名
     * @return InputStream 输入流
     */
    public static InputStream imgWatermarkInt(InputStream inputStream, String waterMarkNameOne, String waterMarkNameTwo, String fileSuffix) {
        try {

            BufferedImage img = ImageIO.read(inputStream);

            int width = img.getWidth();
            int height = img.getHeight();

            int fontSize = (width + height) / 80;


            // 间隔
            int split = fontSize * 2;
            // 文字占用的宽度
            int xWidth1 = getStrWidth(waterMarkNameOne, fontSize);
            int xWidth2 = getStrWidth(waterMarkNameTwo, fontSize);
            int xWidth = Math.max(xWidth1,xWidth2);
            // x,y可以绘制的数量,多加一个补充空白
            int xCanNum = width / xWidth + 1;
            int yCanNum = height / fontSize + 1;
            for (int i = 1; i <= yCanNum; i++) {
                int y = fontSize * i + split * i;
                String waterMarkName = "";
                for (int j = 0; j < xCanNum; j++) {
                    Graphics2D g = img.createGraphics();
                    g.setFont(new Font("黑体", Font.PLAIN, fontSize));
                    g.setColor(new Color(0, 0, 0, 30));
                    g.rotate(0.2);
                    int x = xWidth * j + split * j;
                    //随机水印
                    if (j % 2 == 0) {
                        waterMarkName = waterMarkNameOne;
                    } else {
                        waterMarkName = waterMarkNameTwo;
                    }
                    g.drawString(waterMarkName, x, y - (fontSize + split) * j);
                    g.dispose();
                }
            }


            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(img, fileSuffix, outputStream);

            return new ByteArrayInputStream(outputStream.toByteArray());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 获取字符串占用的宽度
     * <br>
     *
     * @param str      字符串
     * @param fontSize 文字大小
     * @return 字符串占用的宽度
     */
    public static int getStrWidth(String str, int fontSize) {
        char[] chars = str.toCharArray();
        int fontSize2 = fontSize / 2;

        int width = 0;

        for (char c : chars) {
            int len = String.valueOf(c).getBytes().length;
            // 汉字为3,其余1
            // 可能还有一些特殊字符占用2等等,统统计为汉字
            if (len != 1) {
                width += fontSize;
            } else {
                width += fontSize2;
            }
        }
        return width == 0 ? 1 : width;
    }

    /**
     * 图片加水印
     *
     * @param inputStream   输入流
     * @param waterMarkName 添加水印的内容
     * @param fileSuffix    扩展名
     * @return InputStream 新的输入流
     */
    public static InputStream imgWatermarkInt2(InputStream inputStream, String waterMarkName, String fileSuffix) {
        try (InputStream in = inputStream; ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            BufferedImage originalImage = ImageIO.read(in);
            int width = originalImage.getWidth();
            int height = originalImage.getHeight();

            if(width <= 0 || height <= 0){
                throw new IllegalArgumentException("Invalid image size.");
            }

            if(waterMarkName == null || waterMarkName.trim().isEmpty()){
                throw new IllegalArgumentException("Watermark name cannot be empty.");
            }

            // 创建新的BufferedImage对象,并复制原始图像
            BufferedImage newImage = new BufferedImage(width, height, originalImage.getType());
            Graphics2D g = newImage.createGraphics();
            g.drawImage(originalImage, 0, 0, null);

            int fontSize = (width + height) / 80;
            g.setFont(new Font("黑体", Font.PLAIN, fontSize));
            g.setColor(new Color(0, 0, 0, 30));
            g.rotate(0.2);

            // 间隔
            int split = fontSize * 2;
            // 文字占用的宽度
            int xWidth = getStrWidth(waterMarkName, fontSize);
            // x,y可以绘制的数量,多加一个补充空白
            int xCanNum = width / xWidth + 1;
            int yCanNum = height / fontSize + 1;

            // 使用流式API进行操作
            IntStream.range(1, yCanNum + 1)
                    .forEach(i -> {
                        int y = fontSize * i + split * i;
                        IntStream.range(0, xCanNum)
                                .forEach(j -> {
                                    int x = xWidth * j + split * j;
                                    g.drawString(waterMarkName, x, y - (fontSize + split) * j);
                                });
                    });

            g.dispose();

            // 将新的BufferedImage对象写入ByteArrayOutputStream中
            ImageIO.write(newImage, fileSuffix, out);

            // 返回新的InputStream对象
            return new ByteArrayInputStream(out.toByteArray());

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Java添加倾斜水印的示例代码: ```java import java.awt.AlphaComposite; import java.awt.Font; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; public class Watermark { public static void main(String[] args) { try { File imageFile = new File("original_image.jpg"); // 原始图片路径 BufferedImage originalImage = ImageIO.read(imageFile); // 创建一个带有透明度的图片 BufferedImage watermarkedImage = new BufferedImage(originalImage.getWidth(), originalImage.getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = (Graphics2D) watermarkedImage.getGraphics(); // 设置字体和文字大小 Font font = new Font("Arial", Font.BOLD, 36); g2d.setFont(font); // 设置水印文字 String watermarkText = "Watermark"; // 设置水印倾斜角度 double angle = Math.toRadians(-45); // 设置水印透明度 float alpha = 0.5f; // 设置水印颜色 g2d.setColor(java.awt.Color.BLACK); // 设置抗锯齿 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // 将水印文字绘制到图片中 g2d.rotate(angle, originalImage.getWidth() / 2, originalImage.getHeight() / 2); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); g2d.drawString(watermarkText, 100, 100); g2d.dispose(); // 将带有水印图片保存到本地 File outputImageFile = new File("watermarked_image.jpg"); ImageIO.write(watermarkedImage, "png", outputImageFile); } catch (Exception ex) { System.out.println(ex.getMessage()); } } } ``` 这个示例代码中使用了Java的BufferedImage类来载原始图片,并创建一个带有透明度的图片。然后使用Graphics2D类来设置水印的颜色、字体、大小、倾斜角度、透明度、抗锯齿等属性,并将水印文字绘制到图片中。最后将带有水印图片保存到本地。 注意:在实际应用中,可能需要对图片进行缩放、裁剪等操作,因此需要根据实际情况做相应的调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值