Java实现图片添加文字水印的详细步骤与方法教程
本文介绍实现将文字水印添加到图片上的 Java 方法,水印可以是图片形式或者文字形式,其操作较为便捷。

java实现给图片添加水印实现步骤:
java实现给图片添加文字水印
获取原图片对象信息
第一步:获取需要处理的图片
获取图片的方式,通常由两种:
读取本地图片
使用代码来读取位于本地目录 F:\image\1.png 中的图片,具体代码如下:
// 读取原图片信息 得到文件
创建了一个名为 srcImgFile 的文件,其路径为 "F:/image/1.png"。
//将文件对象转化为图片对象
通过 ImageIO 读取源图像文件,得到图像对象 Image srcImg 。
//获取图片的宽
获取源图像 srcImg 的宽度,通过调用 getWidth(null) 方法,将其赋值给整型变量 srcImgWidth 。
//获取图片的高
获取源图像 srcImg 的高度,其高度值为 srcImgHeight,这里的 srcImgHeight 等于 srcImg.getHeight(null)。
System 输出了这样的内容:图片的宽加上 srcImgWidth 。
System.out 会打印出 "图片的高:" 与 srcImgHeight 拼接后的内容。即会输出图片的高的具体数值,该数值为 srcImgHeight 的值。
代码效果如下:
读取网络图片//创建一个URL对象,获取网络图片的地址信息
创建了一个 URL 对象,其地址为 "https://pngimg.com/distr/img/ukraine.png" 。
将 URL 对象的输入流通过 url.openStream()方法获取,进而转化为图片对象。
//获取图片的宽
int srcImgWidth = srcImg.getWidth(null);
//获取图片的高
int srcImgHeight = srcImg.getHeight(null);
System.out.println("图片的宽:"+srcImgWidth);
System.out.println("图片的高:"+srcImgHeight);
代码效果如下:
添加水印
我们已经通过上面的步骤获取到了原始图片信息。接下来需要创建一个画笔,以便添加水印。水印包括文字水印和图片水印。
画笔可以设置水印颜色、字体大小、字体样式等。
创建一个名为 bufImg 的 BufferedImage 对象,其宽度为 srcImgWidth,高度为 srcImgHeight,类型为 BufferedImage.TYPE_INT_RGB。
// 加水印
//创建画笔
创建了一个 Graphics2D 对象 g,该对象是通过对 bufImg 调用 createGraphics() 方法而得到的。
//srcImg 为上面获取到的原始图片的图片对象
使用 srcImg 绘制图像,起始坐标为(0, 0),宽度为 srcImgWidth,高度为 srcImgHeight,超出部分不绘制,使用 null 作为裁剪区域。
//根据图片的背景设置水印颜色
g 设定颜色为一个新的颜色,这个新颜色的 RGB 值分别是 255、255、255,并且透明度为 128。
设置字体时,画笔字体样式为微软雅黑,并且是加粗的,文字大小为 60pt。
g 为某个对象,它设置了新的字体。新字体的名称是“微软雅黑”,字体样式为加粗(Font.BOLD),字体大小为 60。
//设置水印的坐标
//int x=200;
//int y=200;
定义变量 x ,x 的值为 (srcImgWidth - 调用 getWatermarkLength 函数传入 waterMarkContent 和 g 得到的结果) 除以 2 ;
int y=srcImgHeight / 2;
画出水印,其中第一个参数是水印内容,第二个参数是 x 轴坐标,第三个参数是 y 轴坐标。
g.drawString("图片来源:", x, y);
g.dispose();
getWatermarkLength 方法的作用是计算水印内容的长度。
* 获取水印文字的长度
* @param waterMarkContent
* @param g
* @return
获取水印长度的方法如下:需要传入水印内容字符串和 Graphics2D 对象 g,然后在该方法内部进行相关计算以获取水印的长度,并最终将该长度作为整数返回。
获取字体度量对象,即获取当前字体的相关度量信息。然后,使用获取到的字体度量对象来计算给定水印内容字符串的字符宽度。具体来说,是计算水印内容字符串的字符数组中从索引 0 开始到字符串长度的字符宽度。最后,返回计算得到的字符宽度值。
Font 字体说明:
字体的风格有:
size字体大小 默认单位是pt(磅),数字越大,字就越大
需要注意是 水印坐标位置。设置不当,就看不到水印效果。
如何确定水印位置 ?
方法一:设置固定值
①首先,我们要知道图片上的坐标的表示法。具体如下:
先把图片保存到本地,接着选中该图片并点击右键,之后选择“编辑”,再选择“画图”软件打开
将鼠标移至想要添加水印的位置,在左下角能够看到鼠标点击位置所对应的坐标值,获取到这个坐标值后将其写入程序便可。
方法二:根据原图大小进行设置,如放置在原图的中间位置
获取目标图片
经过上述操作后,我们对图片添加文字的工作已处理完毕。然而,它目前仍保存在 Java 对象里。
我们想要看得到效果,需要进行处理,保存图片到本地。
//待存储的地址
字符串 tarImgPath 的值为“F:/image/t.png”。
// 输出图片
创建一个名为 outImgStream 的 FileOutputStream 对象,该对象用于将数据写入到指定的目标图片路径 tarImgPath 中。
使用 ImageIO 将 bufImg 以 "png" 格式写入 outImgStream 中。
System.out.println("添加水印完成");
outImgStream.flush();
outImgStream.close();
执行效果:
执行,目标目录下多了一个t.png的图片:
t.png打开可以看到添加的文字水印,水印添加成功:
完成代码
可能包含一些与列表相关的工具类或方法。
import javax.imageio.ImageIO;
import java.awt.*;
导入 Java 的 awt 图像类中的 BufferedImage 类。
import java.io.File;
使用 Java 语言,引入了用于文件输出流操作的类 java.io.FileOutputStream。
import java.io.IOException;
/**
* 图片添加水印
*/
public class ImageUtils {
公共静态的 void 主方法(字符串数组参数)抛出 IO 异常。
// 读取原图片信息 得到文件(本地图片)
File srcImgFile = new File("F:/image/1.png");
//将文件对象转化为图片对象
Image srcImg = ImageIO.read(srcImgFile);
//获取图片的宽
int srcImgWidth = srcImg.getWidth(null);
//获取图片的高
int srcImgHeight = srcImg.getHeight(null);
System.out.println("图片的宽:"+srcImgWidth);
System.out.println("图片的高:"+srcImgHeight);
//创建一个URL对象,获取网络图片的地址信息(网络图片)
创建了一个 URL 对象,其地址为"https://pngimg.com/distr/img/ukraine.png"
将 URL 对象的输入流通过 url.openStream()方法获取,然后将这个输入流转化为图片对象。
使用 ImageIO 读取 url 打开的流可以得到一个图像对象,这个图像对象被赋值给了变量 srcImg 。
// //获取图片的宽
获取源图像的宽度,通过调用 srcImg 的 getWidth 方法,并传入 null 参数,将返回的宽度值赋给变量 srcImgWidth 。
// //获取图片的高
获取源图像的高度,通过调用 srcImg 的 getHeight 方法,并传入 null 参数,将返回的高度值赋给 srcImgHeight 变量,即 srcImgHeight 等于 srcImg.getHeight(null)的结果。
System.out.println("所涉及的图片其宽度为:" + srcImgWidth);
System.out 会打印出“图片的高:”与 srcImgHeight 进行拼接后的内容。
BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
// 加水印
//创建画笔
Graphics2D g = bufImg.createGraphics();
//绘制原始图片
g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
请明确具体的横线下的句子呀,没有看到具体内容呢,无法进行改写呢。
//根据图片的背景设置水印颜色
g.setColor(new Color(255,255,255,128));
//设置字体 画笔字体样式为微软雅黑,加粗,文字大小为60pt
g.setFont(new Font("微软雅黑", Font.BOLD, 60));
//水印内容
图片的来源是:
//设置水印的坐标(为原图片中间位置)
int x=(srcImgWidth - getWatermarkLength(waterMarkContent, g)) / 2;
int y=srcImgHeight / 2;
//画出水印 第一个参数是水印内容,第二个参数是x轴坐标,第三个参数是y轴坐标
g 绘制字符串(waterMarkContent),位置在 x 和 y 处。
g.dispose();
请提供需要改写的横线下的句子呀,没有具体内容可改写呢。
//待存储的地址
String tarImgPath="F:/image/t.png";
// 输出图片
FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
ImageIO.write(bufImg, "png", outImgStream);
System.out.println("添加水印完成");
outImgStream.flush();
outImgStream.close();
/**
* 获取水印文字的长度
* @param waterMarkContent
* @param g
* @return
*/
public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
java实现给图片添加图片水印
下载水印图片到本地:
水印图片位置:F:\image\s.png
添加图片水印
// 水印文件
字符串 waterMarkImage 的值为 F:/image/s.png。
通过 new File(waterMarkImage) 创建一个文件对象,然后使用 ImageIO.read 方法读取该文件对象,将读取到的内容赋值给 Image srcWaterMark 。
//获取水印图片的宽度
获取源水印的宽度,将其赋值给变量 widthWaterMark,即 widthWaterMark 等于 srcWaterMark.getWidth(null)。
//获取水印图片的高度
获取源水印的高度,该高度赋值给变量 heightWaterMark,获取高度时传入的参数为 null
设置 alpha 透明度时,alpha 需处于范围 [0.0, 1.0] 内,此范围包含边界值,且 alpha 为一个浮点数字
g 设定复合模式,使用 AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.9f)来创建该复合模式。
//绘制水印图片 坐标为中间位置
g 绘制图像 srcWaterMark,位于 (srcImgWidth - widthWaterMark) 除以 2 的位置,在水平方向上;g 绘制图像 srcWaterMark,位于 srcImgHeight 减去 heightWaterMark 的位置,在垂直方向上;g 绘制图像 srcWaterMark,具有指定的宽度 widthWaterMark 和高度 heightWaterMark。
(srcImgHeight 减去 heightWaterMark) 除以 2,widthWaterMark,heightWaterMark,空值;
// 水印文件结束
g.dispose();
完成代码
package com.example.listdemo.utils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 图片添加水印
*/
public class ImageUtils {
public static void main(String[] args) throws IOException {
// 读取原图片信息 得到文件(本地图片)
File srcImgFile = new File("F:/image/1.png");
//将文件对象转化为图片对象
Image srcImg = ImageIO.read(srcImgFile);
//获取图片的宽
int srcImgWidth = srcImg.getWidth(null);
//获取图片的高
int srcImgHeight = srcImg.getHeight(null);
System.out.println("图片的宽:"+srcImgWidth);
System.out.println("图片的高:"+srcImgHeight);
//创建一个URL对象,获取网络图片的地址信息(网络图片)
// URL url = new URL("https://pngimg.com/distr/img/ukraine.png");
// //将URL对象输入流转化为图片对象 (url.openStream()方法,获得一个输入流)
// Image srcImg = ImageIO.read(url.openStream());
// //获取图片的宽
// int srcImgWidth = srcImg.getWidth(null);
// //获取图片的高
// int srcImgHeight = srcImg.getHeight(null);
// System.out.println("图片的宽:"+srcImgWidth);
// System.out.println("图片的高:"+srcImgHeight);
BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
// 加水印
//创建画笔
Graphics2D g = bufImg.createGraphics();
//绘制原始图片
g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
//-------------------------文字水印 start----------------------------
// //根据图片的背景设置水印颜色
g 为某个对象,该对象调用 setColor 方法,传入一个新的 Color 对象,这个 Color 对象的 RGB 值分别为 255、255、255,透明度为 128。
设置字体时,画笔字体样式选用微软雅黑,并且加粗,同时文字大小设定为 60pt。
g 为字体设置了新的字体样式,该字体为“微软雅黑”,字体样式为加粗,字体大小为 60 。
图片的来源是:
// //设置水印的坐标(为原图片中间位置)
定义变量 x,将其赋值为(srcImgWidth 减去 getWatermarkLength(waterMarkContent, g))的结果再除以 2 。
// int y=srcImgHeight / 2;
画出水印,其中第一个参数为水印内容,第二个参数是 x 轴坐标,第三个参数是 y 轴坐标。
g 绘制字符串(waterMarkContent),在 x 位置和 y 位置进行绘制。
// g.dispose();
//-------------------------文字水印 end----------------------------
//-------------------------图片水印 end----------------------------
// 水印文件
String waterMarkImage="F:/image/s.png";
Image srcWaterMark = ImageIO.read(new File(waterMarkImage));
//获取水印图片的宽度
int widthWaterMark= srcWaterMark.getWidth(null);
//获取水印图片的高度
int heightWaterMark = srcWaterMark.getHeight(null);
//设置 alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.9f));
//绘制水印图片 坐标为中间位置
g.drawImage(srcWaterMark, (srcImgWidth - widthWaterMark) / 2,
(srcImgHeight - heightWaterMark) / 2, widthWaterMark, heightWaterMark, null);
// 水印文件结束
g.dispose();
图片上有水印。 图片带有水印。 图片之中存在水印。 图片的上面有水印。 图片的下方有水印。 图片的一侧有水印。 图片的四周有水印。 图片的边缘有水印。 图片的中间有水印。 图片的特定位置有水印。
//待存储的地址
String tarImgPath="F:/image/t.png";
// 输出图片
FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
ImageIO.write(bufImg, "png", outImgStream);
System.out.println("添加水印完成");
outImgStream.flush();
outImgStream.close();
/**
* 获取水印文字的长度
* @param waterMarkContent
* @param g
* @return
*/
public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
代码执行效果
t.png 图片文件里有水印图片,这表明图片水印添加成功了。