JAVA添加水印,平铺和斜对角线我都有!

Hi各位,我是树林子,一个工作两年的程序员。

最近接收到一个开发任务,给照片添加水印功能,最开始是一条对角线的水印,做完后被否掉了,要求平铺,查来查去走了不少坑,所以决定写一篇对小白超级友好,巨详细的文章。

第一种原图:

第一种效果图:

如果以上是你想找的,话不多说,抓紧往下看!!!!!!

调用:

        //1、水印文字
        String logoText = "这只是一个水印 SMALLGROVE";

        //2、获取原始图片路径(我这里只写了本地图片路径,还有一种是从服务器的归档文件中获取)
        String srcImgPath = "d:/srcImg.png"; 

        //3、目标图片路径(加完水印之后的图片,要存放的路径,随便起的名字)
        String targetPath = "d:/targetImg.png";

        //4、给图片添加水印文字(logoText水印内容,srcImgPath原图片路径,targerPath目标图片路径)
        markImageByText(logoText, srcImgPath, targetPath);

水印处理的方法:

     /**
     * 给图片添加水印文字、可设置水印文字的大小、旋转角度、透明度
     * @param logoText  水印内容
     * @param srcImgPath  原图片路径
     * @param targetImgPath  目标图片路径
     */
    public void markImageByText(String logoText, String srcImgPath,
                                String targetImgPath) throws IOException {
        debugLog("图片开始添加水印文字");

        // 1、读取源图片,Image获取图片宽度、高度
        Image scrImg = ImageIO.read(new File(srcImgPath));
        BufferedImage buffImg = new BufferedImage(scrImg.getWidth(null), scrImg.getHeight(null), BufferedImage.TYPE_INT_RGB);

        // 2、得到画笔对象
        Graphics2D graphics = buffImg.createGraphics();

        // 3、设置对线段的锯齿状边缘处理
        graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        graphics.drawImage(scrImg.getScaledInstance(scrImg.getWidth(null), scrImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0, null);

        // 4、设置水印倾斜度,这里是在图片的对角线上
        // 对角线长度lengthOfDiagonal
        double lengthOfDiagonal = Math.sqrt(Math.pow(buffImg.getWidth(),2) + Math.pow(buffImg.getHeight(),2));
        double v = (Math.pow(buffImg.getWidth(), 2) + Math.pow(lengthOfDiagonal, 2) - Math.pow(buffImg.getHeight(), 2)) / (2 * buffImg.getWidth() * lengthOfDiagonal);
        //get到了一个弧度数
        double acos = Math.acos(v); 
        double myDegree = Math.toDegrees(acos);
        //这里的负号决定对角线-Math.toRadians(myDegree)
        graphics.rotate(-Math.toRadians(myDegree),
                (double) buffImg.getWidth() / 2,
                (double) buffImg.getHeight() / 2);

        // 5、设置水印文字颜色
        graphics.setColor(Color.RED);

        // 6、获取源图片的宽度和高度
        int width = scrImg.getWidth(null);
        int heigth = scrImg.getHeight(null);

        // 7、设置水印文字大小(根据原图的宽、高度,我这里是哪个长就取哪个,再除上水印字符串长度,记为size)
        int size = 0;
        if (width >= heigth) {
            size = width / logoText.length();
        } else {
            size = heigth / logoText.length();
        }
        //Font是JAVA中的字体类,PLAIN:普通样式常量;BOLD:粗体样式常量;ITALIC:斜体样式常量
        //如下初始化对象:Font font = new Font("宋体" , Font.BOLD , 23);该字体表示23磅粗体的宋体字
        graphics.setFont(new Font("宋体", Font.PLAIN, size));

        //8、设置透明度
        graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                0.3f));

        //9、设置文字位置
        FontDesignMetrics metrics = FontDesignMetrics.getMetrics(graphics.getFont());
        //获取文字宽度
        int strWidth = metrics.stringWidth(logoText);
        int strHeight = metrics.getHeight();
        //文字在画布上的坐标
        int left = (width - strWidth) / 2; 
        //有条基线,加上ascent,相当于画布要向上移动(或是文字向下移),才能保证文字是居中的
        int top = (heigth - strHeight) / 2 + metrics.getAscent(); 

        //10、水印文字开始动工了,文字内容,x,y坐标
        graphics.drawString(logoText, left, top);

        //11、释放资源
        graphics.dispose();

        //12、生成图片
        try {
            OutputStream os = null;
            os = new FileOutputStream(targetImgPath);
            ImageIO.write(buffImg, "png", os);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        debugLog("图片完成添加水印文字");
    }

第二种原图:

第二种效果图:

  /**
     * 给图片添加水印文字、可设置水印文字的大小、旋转角度、透明度
     *
     * @param logoText   水印内容
     * @param srcImgPath 原图片路径
     * @param targerPath 目标图片路径
     */
    public void markImageByText(String logoText, String srcImgPath,
                                String targerPath) throws IOException {
        debugLog("图片开始添加水印文字");

        // 1、读取源图片,Image获取图片宽度、高度
        Image scrImg = ImageIO.read(new File(srcImgPath));
        BufferedImage buffImg = new BufferedImage(scrImg.getWidth(null), scrImg.getHeight(null), BufferedImage.TYPE_INT_RGB);

        // 2、得到画笔对象
        Graphics2D graphics = buffImg.createGraphics();

        // 3、设置对线段的锯齿状边缘处理
        graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        graphics.drawImage(scrImg.getScaledInstance(scrImg.getWidth(null), scrImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0, null);

        // 4、设置水印倾斜度,这里是在图片的对角线上
        // 对角线长度lengthOfDiagonal
        double lengthOfDiagonal = Math.sqrt(Math.pow(buffImg.getWidth(), 2) + Math.pow(buffImg.getHeight(), 2));
        double v = (Math.pow(buffImg.getWidth(), 2) + Math.pow(lengthOfDiagonal, 2) - Math.pow(buffImg.getHeight(), 2)) / (2 * buffImg.getWidth() * lengthOfDiagonal);
        //get到了一个弧度数
        double acos = Math.acos(v);
        double myDegree = Math.toDegrees(acos);
        //这里的负号决定对角线-Math.toRadians(myDegree)
        graphics.rotate(-Math.toRadians(myDegree),
                (double) buffImg.getWidth() / 2,
                (double) buffImg.getHeight() / 2);

        // 5、设置水印文字颜色
        graphics.setColor(Color.DARK_GRAY);


        // 6、获取源图片的宽度和高度
        int width = scrImg.getWidth(null);
        int heigth = scrImg.getHeight(null);


        graphics.setFont(new Font("微软雅黑", Font.BOLD, 50));

        //8、设置透明度
        graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                0.2f));

        //9、设置文字位置
        FontDesignMetrics metrics = FontDesignMetrics.getMetrics(graphics.getFont());
        //获取文字宽度
        int strWidth = metrics.stringWidth(logoText);

        int xNum = width / strWidth + 1;

        int yNum = heigth / 50 + 1;

        int split = 50;

        for (int i = 1; i <= 2 * yNum; i++) {
            int y = -heigth + 50 * i + 5 * split * i;
            for (int j = 0; j < xNum; j++) {
                int x = strWidth * j + 3 * split * j;

                graphics.drawString(logoText, x, y);
            }
        }

        //11、释放资源
        graphics.dispose();

        //12、生成图片
        try {
            OutputStream os = null;
            os = new FileOutputStream(targerPath);
            ImageIO.write(buffImg, "jpg", os);
        } catch (
                FileNotFoundException e) {
            e.printStackTrace();
        }

        debugLog("图片完成添加水印文字");
    }

平时会更一些日常工作中遇到的问题,以此来记录自己的成长。

下期见面!Bye!

  • 12
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,我了解了您的问题。您可以使用Java的Graphics2D类来添加文字水印和图片水印。以下是一个简单的例子: ```java import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; public class Watermark { public static void main(String[] args) { try { // 读取原始图片 BufferedImage originalImage = ImageIO.read(new File("original.png")); // 创建带有透明度的图片 BufferedImage watermarkedImage = new BufferedImage(originalImage.getWidth(), originalImage.getHeight(), BufferedImage.TYPE_INT_ARGB); // 获取 Graphics2D 对象 Graphics2D g2d = (Graphics2D) watermarkedImage.getGraphics(); // 在图片上绘制原始图片 g2d.drawImage(originalImage, 0, 0, null); // 设置文字水印 String text = "Watermark Text"; Font font = new Font("Arial", Font.BOLD, 48); g2d.setFont(font); g2d.setColor(Color.WHITE); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); FontMetrics fontMetrics = g2d.getFontMetrics(); Rectangle2D rect = fontMetrics.getStringBounds(text, g2d); g2d.drawString(text, (originalImage.getWidth() - (int) rect.getWidth()) / 2, originalImage.getHeight() / 2); // 设置图片水印 BufferedImage watermarkImage = ImageIO.read(new File("watermark.png")); int x = originalImage.getWidth() - watermarkImage.getWidth() - 10; int y = originalImage.getHeight() - watermarkImage.getHeight() - 10; g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); g2d.drawImage(watermarkImage, x, y, null); // 保存水印图片 ImageIO.write(watermarkedImage, "png", new File("watermarked.png")); // 释放资源 g2d.dispose(); System.out.println("Watermark applied."); } catch (Exception ex) { System.out.println(ex.getMessage()); } } } ``` 您可以根据您的需求调整文字和图片的位置、大小、透明度等参数以实现您想要的效果。希望能对您有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值