Java实现添加文字水印&图片水印的方法详解

 更新时间:2023年02月06日 15:32:56   作者:全村最野的狗  
为图片添加水印的主要作用是保护图片版权,防止图片被未经授权的人使用或传播。本文为大家介绍了Java实现添加文字水印&图片水印的具体方法,需要的可以参考一下

为什么要给图片添加水印

为图片添加水印的主要作用是保护图片版权,防止图片被未经授权的人使用或传播。

通常情况下,图片水印会包含图片作者的名字、版权信息或公司商标等信息,这些信息可以帮助识别图片的所有者,并对未经授权的使用进行追究

此外,图片水印还可以用于提醒人们图片的使用限制,例如是否需要授权、是否可以用于商业用途等。

除此之外,图片水印还可以用于增加图片的视觉吸引力或宣传性,例如可以在图片中添加品牌 logo 或宣传标语等。

总的来说,图片水印的主要作用是保护图片版权和提醒人们图片的使用限制,但也可以用于提升图片的视觉效果和宣传性。

绘制文字水印

为图片添加水印是一种常用的图片处理技术。在 Java 中可以使用 Graphics2D 类来绘制水印。

以下是一个简单的例子,展示了如何在图片的右下角添加一个水印:

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class Watermark {
    public static void main(String[] args) {
        // 读取原图片
        BufferedImage image = null;
        try {
            image = ImageIO.read(new File("original.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 获取图片的宽度和高度
        int width = image.getWidth();
        int height = image.getHeight();
        // 创建一个图片缓存对象
        BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 获取图片的画笔
        Graphics2D g = newImage.createGraphics();
        // 将原图片绘制到缓存图片上
        g.drawImage(image, 0, 0, width, height, null);
        // 设置水印的字体样式
        g.setFont(new Font("微软雅黑", Font.BOLD, 20));
        // 设置水印的颜色
        g.setColor(Color.red);
        // 设置水印的位置
        g.drawString("Hello World!", width - 120, height - 10);
        // 释放图形上下文使用的系统资源
        g.dispose();
        // 保存带水印的图片
        try {
            ImageIO.write(newImage, "jpg", new File("watermarked.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

动态计算字符串的宽度

如果你已经知道了字符串的大小(size)和内容(str),想要计算字符串的宽度,可以使用以下方法:

首先创建一个 Font 对象,使用该对象的 getStringBounds 方法计算字符串的宽度。

import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;

public class StringWidth {
    public static void main(String[] args) {
        // 字符串内容
        String str = "Hello World!";
        // 字体大小
        int size = 20;
        // 创建字体对象
        Font font = new Font("微软雅黑", Font.BOLD, size);
        // 创建字体渲染上下文
        FontRenderContext frc = new FontRenderContext(null, true, true);
        // 计算字符串的宽度
        Rectangle2D bounds = font.getStringBounds(str, frc);
        // 输出字符串的宽度
        System.out.println(bounds.getWidth());
    }
}

在这段代码中,我们首先创建了一个 Font 对象,然后使用该对象的 getStringBounds 方法计算字符串的宽度。

注意,在调用 getStringBounds 方法时,需要传入一个 FontRenderContext 对象,该对象用于描述字体的渲染环境,可以影响字符串的显示效果。

最后,计算出的字符串宽度是一个 Rectangle2D 对象,你可以使用 getWidth 方法来获取实际的宽度值。

自适应文字水印位置

可以看到,我们添加的水印已经超出了图片的范围,导致显示不完全,出现这种结果的原因是因为我们默认字符的宽度为120px.您可以通过上面介绍的动态计算字符宽度来让水印始终显示在图片上。

import java.awt.Color;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class Watermark {
    public static void main(String[] args) {
        // 读取原图片
        BufferedImage image = null;
        try {
            image = ImageIO.read(new File("original.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 获取图片的宽度和高度
        int width = image.getWidth();
        int height = image.getHeight();
        // 创建一个图片缓存对象
        BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 获取图片的画笔
        Graphics2D g = newImage.createGraphics();
        // 字符串内容
        String str = "Hello World!";
        // 字体大小
        int size = 20;
        // 创建字体对象
        Font font = new Font("微软雅黑", Font.BOLD, size);
        // 创建字体渲染上下文
        FontRenderContext frc = new FontRenderContext(null, true, true);
        // 计算字符串的宽度和高度
        Rectangle2D bounds = font.getStringBounds(str, frc);
        // 字符宽度
        int strWidth = (int)bounds.getWidth();
        // 字符高度
        int strHeight = (int)bounds.getHeight();
        // 将原图片绘制到缓存图片上
        g.drawImage(image, 0, 0, width, height, null);
        // 设置水印的字体样式
        g.setFont(font);
        // 设置水印的颜色
        g.setColor(Color.red);
        // 设置水印的位置
        g.drawString("Hello World!", width - strWidth - 10, height - strHeight - 10);
        // 释放图形上下文使用的系统资源
        g.dispose();
        // 保存带水印的图片
        try {
            ImageIO.write(newImage, "jpg", new File("watermarked.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

绘制图片水印

如果你想在 png 格式的图片上绘制透明的图片水印,可以使用以下方法:

首先读取原图片和水印图片,然后使用 Graphics2D 类的 drawImage 方法将水印图片绘制到原图片上,最后使用 setComposite 方法设置水印图片的 alpha 通道值来调整水印的透明度。

紫色部分为图片水印。

具体实现如下:

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class TransparentWatermark {
    public static void main(String[] args) {
        // 读取原图片
        BufferedImage image = null;
        try {
            image = ImageIO.read(new File("original.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 获取图片的宽度和高度
        int width = image.getWidth();
        int height = image.getHeight();
        // 创建一个图片缓存对象
        BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 获取图片的画笔
        Graphics2D g = newImage.createGraphics();
        // 将原图片绘制到缓存图片上
        g.drawImage(image, 0, 0, width, height, null);
        // 读取水印图片
        BufferedImage watermark = null;
        try {
            watermark = ImageIO.read(new File("watermark.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 获取水印图片的宽度和高度
        int wmWidth = watermark.getWidth();
        int wmHeight = watermark.getHeight();
        // 设置水印图片的透明度
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5f));
        // 绘制水印图片
        g.drawImage(watermark, width - wmWidth - 10, height - wmHeight - 10, wmWidth, wmHeight, null);
        // 释放图形上下文使用的系统资源
        g.dispose();
        // 保存带水印的图片
        try {
            ImageIO.write(newImage, "png", new File("watermarked.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

提升图片处理速度

目前我们添加文字水印和图片水印耗时都在 700ms - 2000ms

可以考虑以下几种方法来提升速度:

  • 使用多线程:如果你需要批量添加文字水印,可以考虑使用多线程的方式来加速处理速度。例如,你可以将图片分成多份,每份使用一个线程处理,最后再将结果合并。
  • 使用更快的图片处理库:如果你使用的是 Java 原生的图片处理工具(例如 java.awt 包),可以考虑使用更快的图片处理库,例如 OpenCV、Imaging、Thumbnails 等。这些库通常具有更快的处理速度,并且支持更多的图片格式和操作。
  • 减少图片的质量:如果你的图片尺寸较大,可以考虑将图片的质量压缩到一个较低的水平,这样可以减少图片的体积,从而加快处理速度。
  • 优化代码:如果你的代码有一些低效的地方,可以考虑优化代码,提升程序的执行效率。例如,可以避免使用过多的循环和分支语句,或者使用更快的算法等。

到此这篇关于Java实现添加文字水印&图片水印的方法详解的文章就介绍到这了,更多相关Java添加水印内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一文详解spring注解配置bean的初始化方法和销毁方法

    一文详解spring注解配置bean的初始化方法和销毁方法

    本篇我们讲解下spring项目中如何为bean指定初始化方法和销毁方法。当spring完成bean的属性赋值之后,就会执行bean的初始化方法,而当spring要销毁bean实例的时候,也会调用bean的销毁方法。文中有详细的代码实例,需要的朋友可以参考下
    2023-05-05
  • JavaWeb 网上书店 注册和登陆功能案例详解

    JavaWeb 网上书店 注册和登陆功能案例详解

    这篇文章主要介绍了JavaWeb 网上书店 注册和登陆功能,结合具体案例形式详细分析了JavaWeb 网上书店 注册和登陆功能具体实现步骤、操作技巧与注意事项,需要的朋友可以参考下
    2019-08-08
  • Java Swing仿QQ登录界面效果

    Java Swing仿QQ登录界面效果

    这篇文章主要为大家详细介绍了Java Swing仿QQ登录界面效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • 解决新版idea新建文件没有XML和Resource Bundle文件问题

    解决新版idea新建文件没有XML和Resource Bundle文件问题

    这篇文章主要介绍了解决新版idea新建文件没有XML和Resource Bundle文件问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • java构建Stream流的多种方式总结

    java构建Stream流的多种方式总结

    Java 8引入了Stream流作为一项新的特性,它是用来处理集合数据的一种函数式编程方式,本文为大家整理了多种java构建Stream流的方式,希望对大家有所帮助
    2023-11-11
  • Java中的static关键字全面解析

    Java中的static关键字全面解析

    这篇文章主要介绍了Java中的static关键字全面解析的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-06-06
  • java反射方式创建代码详解

    java反射方式创建代码详解

    在本篇文章里小编给大家整理的是一篇关于java反射方式创建代码详解内容,对此有兴趣的朋友们可以学习下。
    2021-01-01
  • springboot中通过lua脚本来获取序列号的方法

    springboot中通过lua脚本来获取序列号的方法

    这篇文章主要介绍了springboot中通过lua脚本来获取序列号的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • Maven仓库的具体使用(本地仓库+远程仓库)

    Maven仓库的具体使用(本地仓库+远程仓库)

    Maven 在某个统一的位置存储所有项目的构件,这个统一的位置,我们就称之为仓库,本文主要介绍了Maven仓库的具体使用(本地仓库+远程仓库),感兴趣的可以了解一下
    2023-11-11
  • Spring Cloud 整合 nacos实现动态配置中心的详细步骤

    Spring Cloud 整合 nacos实现动态配置中心的详细步骤

    这篇文章主要介绍了Spring Cloud 整合 nacos 实现动态配置中心,整合步骤是通过添加依赖新建nacos配置,本文分步骤通过实例代码给大家详细讲解,需要的朋友可以参考下
    2022-10-10

最新评论