当前位置: 首页 > news >正文

java实现图片添加水印

文章目录

  • 前言
  • 一、工具类WatermarkUtil
  • 二、工具类介绍
    • 2.1 图片来源类型
    • 2.2 水印类型
    • 2.3 读取本地图片
    • 2.4 读取网络图片
    • 2.5 水印处理
    • 2.6 添加水印
  • 三、测试添加水印
  • 总结


前言

给图片添加水印是一个很常见的需求,一般是用来防盗用。比如我们csdn上面写的文章中,如果包含图片,那么可以给图片带上个人水印标志。笔者是因为工作需要,特此研究一下使用java实现给图片加水印的方法。


一、工具类WatermarkUtil

完整的工具类代码如下

package com.hulei.watermark;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;/*** 添加水印util*/
public class WatermarkUtil {/*** 添加水印** @param pictureSourceType 图片来源类型* @param watermarkType     水印类型* @param path              图片路径* @param watermark         水印内容(文字水印内容/图片水印的存放路径)* @param formatName        图片格式* @param targetPath        输出图片存放路径* @param color             水印颜色*/public static void addWatermark(PictureSourceType pictureSourceType, WatermarkType watermarkType, String path, String watermark, String formatName, String targetPath, Color color) {if (null == pictureSourceType) {throw new RuntimeException("图片来源类型不能为空");}if (null == watermarkType) {throw new RuntimeException("水印类型不能为空");}Image image;if (pictureSourceType == PictureSourceType.LOCAL_PICTURE) {// 读取本地图片image = readLocalPicture(path);} else {// 读取网络图片image = readNetworkPicture(path);}// 水印处理manageWatermark(image, watermarkType, watermark, formatName, targetPath, color);}//图片来源类型枚举public enum PictureSourceType {//本地图片LOCAL_PICTURE,//网络图片NETWORK_PICTURE;}//水印类型枚举public enum WatermarkType {//文字水印TEXT_WATERMARK,//图片水印IMAGE_WATERMARK;}/*** 读取本地图片** @param path 本地图片存放路径*/public static Image readLocalPicture(String path) {if (null == path) {throw new RuntimeException("本地图片路径不能为空");}// 读取原图片信息 得到文件File srcImgFile = new File(path);try {// 将文件对象转化为图片对象return ImageIO.read(srcImgFile);} catch (IOException e) {throw new RuntimeException(e);}}/*** 读取网络图片** @param path 网络图片地址*/public static Image readNetworkPicture(String path) {if (null == path) {throw new RuntimeException("网络图片路径不能为空");}try {// 创建一个URL对象,获取网络图片的地址信息URL url = new URL(path);// 将URL对象输入流转化为图片对象 (url.openStream()方法,获得一个输入流)BufferedImage bugImg = ImageIO.read(url.openStream());if (null == bugImg) {throw new RuntimeException("网络图片地址不正确");}return bugImg;} catch (IOException e) {throw new RuntimeException(e);}}/*** 水印处理** @param image         图片对象* @param watermarkType 水印类型(1-文字水印 2-图片水印)* @param watermark     水印内容(文字水印内容/图片水印的存放路径)* @param formatName    图片格式* @param tarImgPath    输出图片存放路径* @param color         水印颜色*/public static void manageWatermark(Image image, WatermarkType watermarkType, String watermark, String formatName, String tarImgPath, Color color) {int imgWidth = image.getWidth(null);int imgHeight = image.getHeight(null);BufferedImage bufImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);// 加水印,创建画笔Graphics2D graphics = bufImg.createGraphics();// 绘制原始图片graphics.drawImage(image, 0, 0, imgWidth, imgHeight, null);// 校验水印的类型if (watermarkType == WatermarkType.TEXT_WATERMARK) {if (watermark.isEmpty()) {throw new RuntimeException("文字水印内容不能为空");}// 添加文字水印:// 根据图片的背景设置水印颜色graphics.setColor(color == null ? Color.RED : color);// 设置字体  画笔字体样式为微软雅黑,加粗,文字大小为45ptgraphics.setFont(new Font("微软雅黑", Font.BOLD, 45));// 设置水印的坐标(为原图片中间位置)int x = (imgWidth - getWatermarkLength(watermark, graphics)) / 2;int y = imgHeight / 2;// 画出水印 第一个参数是水印内容,第二个参数是x轴坐标,第三个参数是y轴坐标graphics.drawString(watermark, x, y);graphics.dispose();} else {// 添加图片水印:if (watermark.isEmpty()) {throw new RuntimeException("图片水印存放路径不能为空");}Image srcWatermark = readLocalPicture(watermark);int watermarkWidth = srcWatermark.getWidth(null);int watermarkHeight = srcWatermark.getHeight(null);// 设置 alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.9f));// 绘制水印图片  坐标为中间位置graphics.drawImage(srcWatermark, (imgWidth - watermarkWidth) / 2, (imgHeight - watermarkHeight) / 2, watermarkWidth, watermarkHeight, null);graphics.dispose();}// 输出图片try {FileOutputStream outImgStream = new FileOutputStream(tarImgPath);ImageIO.write(bufImg, formatName, outImgStream);outImgStream.flush();outImgStream.close();} catch (IOException e) {throw new RuntimeException(e);}}/*** 获取水印文字的长度** @param watermarkContent 文字水印内容* @param graphics         图像类*/private static int getWatermarkLength(String watermarkContent, Graphics2D graphics) {return graphics.getFontMetrics(graphics.getFont()).charsWidth(watermarkContent.toCharArray(), 0, watermarkContent.length());}}

二、工具类介绍

2.1 图片来源类型

这个枚举主要包括两个待添加水印的图片来源类型,分别为本地图片和网络图片,即是给本地图片加水印还是网络图片加水印。

    //图片来源类型枚举public enum PictureSourceType {//本地图片LOCAL_PICTURE,//网络图片NETWORK_PICTURE;}

2.2 水印类型

给图片加水印,水印也分为两种类型,分别为文字水印和图片水印,图片水印即是把图片作为水印添加到另外一个图片上。

    //水印类型枚举public enum WatermarkType {//文字水印TEXT_WATERMARK,//图片水印IMAGE_WATERMARK;}

2.3 读取本地图片

该函数用于读取指定路径下的本地图片,并返回一个Image对象。如果路径为空,则抛出运行时异常;如果读取图片失败,则将捕获的IOException转换为运行时异常抛出。
在这里插入图片描述

2.4 读取网络图片

该函数用于读取网络图片。首先检查传入的网络图片地址是否为空,如果为空则抛出运行时异常。然后通过URL对象获取网络图片的输入流,并使用ImageIO的read方法将输入流转化为图片对象。如果转化失败则抛出运行时异常。最后返回转化成功的图片对象。

在这里插入图片描述

2.5 水印处理

该函数用于给图片添加水印,支持文字水印和图片水印两种类型。根据传入的水印类型,选择添加文字水印或图片水印。对于文字水印,会根据传入的颜色设置水印颜色,设置字体样式为微软雅黑加粗45pt,将水印内容居中显示在图片上。对于图片水印,会读取指定路径的图片,并将其居中显示在图片上。最后将添加了水印的图片输出到指定路径。
在这里插入图片描述

2.6 添加水印

该函数用于给图片添加水印。根据传入的图片来源类型和水印类型,读取相应的图片并进行水印处理,最后将处理后的图片保存到指定路径。具体流程如下:

  • 检查传入的图片来源类型和水印类型是否为空,若为空则抛出异常。
  • 根据图片来源类型,读取本地图片或网络图片。
  • 调用manageWatermark方法对图片进行水印处理,处理包括水印类型、水印内容、图片格式、输出路径和水印颜色等参数。
  • 完成水印处理后,函数执行结束。
    public static void addWatermark(PictureSourceType pictureSourceType, WatermarkType watermarkType, String path, String watermark, String formatName, String targetPath, Color color) {if (null == pictureSourceType) {throw new RuntimeException("图片来源类型不能为空");}if (null == watermarkType) {throw new RuntimeException("水印类型不能为空");}Image image;if (pictureSourceType == PictureSourceType.LOCAL_PICTURE) {// 读取本地图片image = readLocalPicture(path);} else {// 读取网络图片image = readNetworkPicture(path);}// 水印处理manageWatermark(image, watermarkType, watermark, formatName, targetPath, color);}

三、测试添加水印

主要功能是给图片添加水印。具体来说,函数使用了WatermarkUtil工具类的addWatermark方法,实现了给本地图片和网络图片添加文字水印和图片水印,并将添加水印后的图片保存到指定路径。函数中定义了图片的本地路径、网络地址、水印内容、水印图片路径、输出格式以及水印颜色等参数。通过调用addWatermark方法,实现了给本地图片和网络图片添加文字水印和图片水印的功能。

测试类完整代码

package com.hulei.watermark;import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import java.awt.*;@SpringBootTest
class AddWaterMarkApplicationTests {@Testvoid contextLoads() {// 本地图片路径String localPath = "D:/localImage.png";// 网络图片地址String networkPath = "https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2023%2F0329%2F31dc71faj00rs8saz004sd000vc015sm.jpg&thumbnail=660x2147483647&quality=80&type=jpg";// 文字水印内容String textWatermark = "Hello World!";// 图片水印路径String pictureWatermark = "D:/imageWaterMark.png";//输出图片的格式String outputFormat = "jpg";//本地图片添加文字水印输出地址String local_image_text_watermark = "E:/local_image_text_watermark.jpg";//本地图片添加图片水印输出地址String local_image_picture_watermark = "E:/local_image_picture_watermark.jpg";//网络图片添加文字水印输出地址String network_image_text_watermark = "E:/network_image_text_watermark.jpg";//网络图片添加图片水印输出地址String network_image_picture_watermark = "E:/network_image_picture_watermark.jpg";// 本地图片 添加文字水印WatermarkUtil.addWatermark(WatermarkUtil.PictureSourceType.LOCAL_PICTURE, WatermarkUtil.WatermarkType.TEXT_WATERMARK, localPath,textWatermark,outputFormat,local_image_text_watermark,Color.RED);// 本地图片 添加图片水印,图片水印不需要设置颜色WatermarkUtil.addWatermark(WatermarkUtil.PictureSourceType.LOCAL_PICTURE, WatermarkUtil.WatermarkType.IMAGE_WATERMARK, localPath, pictureWatermark,outputFormat,local_image_picture_watermark,null);// 网络图片 添加文字水印WatermarkUtil.addWatermark(WatermarkUtil.PictureSourceType.NETWORK_PICTURE, WatermarkUtil.WatermarkType.TEXT_WATERMARK, networkPath, textWatermark,outputFormat,network_image_text_watermark,Color.RED);// 网络图片 添加图片水印,图片水印不需要设置颜色WatermarkUtil.addWatermark(WatermarkUtil.PictureSourceType.NETWORK_PICTURE, WatermarkUtil.WatermarkType.IMAGE_WATERMARK, networkPath, pictureWatermark,outputFormat,network_image_picture_watermark,null);}}

注意:png图片不能是非png格式的图片通过改名和修改后缀得到,否则将会读取不到图片

这两个图片分别为本地图片和作为水印的图片,笔者放在了D盘根目录下
在这里插入图片描述

点击测试类方法后会在E盘得到四张不同图片,依次如下:

  1. 本地图片添加文字水印

在这里插入图片描述

  1. 本地图片添加图片水印

在这里插入图片描述

  1. 网络图片添加文字水印

在这里插入图片描述

  1. 网络图片添加图片水印

在这里插入图片描述

总结

以上就是笔者在探索使用java为图片添加水印完整过程,使用的都是java原生提供的处理图片的方式。使用的图片都是一些网上随便找的,如有侵权请评论区找我,我会及时撤下哈。

http://www.lryc.cn/news/386628.html

相关文章:

  • CSS规则——font-face
  • 【单片机毕业设计选题24034】-基于STM32的手机智能充电系统
  • [C++][数据结构][图][中][图的遍历][最小生成树]详细讲解
  • 退市新规解读—财务类强制退市
  • 小程序的生命周期使用方法和应用场景
  • 什么是C++模块化系统?C++20的模块化系统。
  • 智慧校园-档案管理系统总体概述
  • 文心一言 VS 讯飞星火 VS chatgpt (290)-- 算法导论21.3 3题
  • 逻辑回归梯度推导
  • Python 使用函数输出一个整数的逆序数
  • 【Linux】Wmware Esxi磁盘扩容
  • 树莓派4B_OpenCv学习笔记15:OpenCv定位物体实时坐标
  • MySQL之如何定位慢查询
  • Open3D 删除点云中重复的点
  • 填报志愿选专业是兴趣重要还是前景重要?
  • python开发基础——day9 函数基础与函数参数
  • STM32——使用TIM输出比较产生PWM波形控制舵机转角
  • 第十五章 集合(set)(Python)
  • 面试-javaIO机制
  • 在.NET Core中,config和ConfigureServices的区别和作用
  • App Inventor 2 如何实现多个定时功能?
  • 技术驱动的音乐变革:AI带来的产业重塑
  • 重生之我要学后端0--HTTP协议和RESTful APIs
  • 深度之眼(二十八)——神经网络基础知识(三)-卷积神经网络
  • AI Infra简单记录
  • 三英战吕布 | 第5集 | 温酒斩华雄 | 竖子不足与谋 | 三国演义 | 逐鹿群雄
  • 【C语言】自定义类型:结构体
  • 算法金 | 决策树、随机森林、bagging、boosting、Adaboost、GBDT、XGBoost 算法大全
  • [每周一更]-(第103期):GIT初始化子模块
  • 单例模式---线程安全实现