Java实现添加文字水印、图片水印功能实战

2023-09-15 18:30:04

java实现给图片添加水印实现步骤:

获取原图片对象信息(本地图片或网络图片)
添加水印(设置水印颜色、字体、坐标等)
处理输出目标图片

java实现给图片添加文字水印

获取原图片对象信息

第一步:获取需要处理的图片

获取图片的方式,通常由两种:

  • 一种是通过下载到本地,从本地读取(本地图片);
  • 另外一种是通过网络地址进行读取(网络图片)

读取本地图片

在这里插入图片描述
读取本地目录(F:\image\1.png)下图片

// 读取原图片信息 得到文件
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();
//srcImg 为上面获取到的原始图片的图片对象
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=200;
//int y=200;
int x=(srcImgWidth - getWatermarkLength(waterMarkContent, g)) / 2;
int y=srcImgHeight / 2;
//画出水印 第一个参数是水印内容,第二个参数是x轴坐标,第三个参数是y轴坐标
g.drawString("图片来源:https://image.baidu.com/", x, y);
g.dispose();

getWatermarkLength方法用于计算水印内容的长度:

/**
 * 获取水印文字的长度
 * @param waterMarkContent
 * @param g
 * @return
 */
public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
    return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
}

Font 字体说明:

  • Font 类的构造函数为:public Font(String familyName, int style, int size)
  • 参数说明:第一个参数为字体类型,第二个参数为字体风格,第三个参数为字体大小。

字体的风格有:

  • Font.PLAIN(普通)
  • Font.BOLD(加粗)
  • Font.ITALIC(斜体)
  • Font.BOLD+Font.ITALIC(粗斜体)

size字体大小 默认单位是pt(磅),数字越大,字就越大

如何确定水印位置 ?

方法一:设置固定值

①首先,我们要知道图片上的坐标的表示法。具体如下:
在这里插入图片描述
②将图片保存到本地,然后选中图片点击右键,编辑,选择“画图”软件打开

③将鼠标移动到想要添加水印的位置,左下角可以看到鼠标点击位置对应的坐标值,拿到这个坐标值写入程序即可。
在这里插入图片描述
方法二:根据原图大小进行设置,如放置在原图的中间位置

  • x轴坐标:(原始图的宽度 - 水印的宽度) / 2
  • y轴坐标:(原始图的高度 - 水印的高度) / 2

获取目标图片

图片添加文字就已经处理完成了。但他现在还保存在Java对象中。

我们想要看得到效果,需要进行处理,保存图片到本地。

//待存储的地址
String tarImgPath="F:/image/t.png";
// 输出图片
FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
ImageIO.write(bufImg, "png", outImgStream);
System.out.println("添加水印完成");
outImgStream.flush();
outImgStream.close();

在这里插入图片描述

整体代码

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(new Color(255,255,255,128));
        //设置字体  画笔字体样式为微软雅黑,加粗,文字大小为60pt
        g.setFont(new Font("微软雅黑", Font.BOLD, 60));
        //水印内容
        String waterMarkContent="图片来源:https://image.baidu.com/";
        //设置水印的坐标(为原图片中间位置)
        int x=(srcImgWidth - getWatermarkLength(waterMarkContent, g)) / 2;
        int y=srcImgHeight / 2;
        //画出水印 第一个参数是水印内容,第二个参数是x轴坐标,第三个参数是y轴坐标
        g.drawString(waterMarkContent, x, y);
        g.dispose();
        //-------------------------文字水印 end----------------------------
        //待存储的地址
        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实现给图片添加图片水印

在这里插入图片描述

添加图片水印

// 水印文件
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();

完整代码

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(new Color(255,255,255,128));
        //        //设置字体  画笔字体样式为微软雅黑,加粗,文字大小为60pt
        //        g.setFont(new Font("微软雅黑", Font.BOLD, 60));
        //        String waterMarkContent="图片来源:https://image.baidu.com/";
        //        //设置水印的坐标(为原图片中间位置)
        //        int x=(srcImgWidth - getWatermarkLength(waterMarkContent, g)) / 2;
        //        int y=srcImgHeight / 2;
        //        //画出水印 第一个参数是水印内容,第二个参数是x轴坐标,第三个参数是y轴坐标
        //        g.drawString(waterMarkContent, x, y);
        //        g.dispose();
        //-------------------------文字水印 end----------------------------

        //-------------------------图片水印 start----------------------------
        // 水印文件
        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();
        //-------------------------图片水印 end----------------------------

        //待存储的地址
        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());
    }
}
更多推荐

MySQL 深分页优化

在实际应用场景中,列表分页查询是很常见的。假设现在存在某张表,已知ID是主键,针对user_name建立了二级索引。针对该表进行分页查询。select*fromtableorderbyidlimitoffset,size;那么同样都是获取10条数据,查询第一页和查询第一百页的速度一样吗?首先先回忆下MySQL查询语句的

Python文件操作和管理指南:打开、读取、写入和管理文件

文章目录文件(File)打开文件使用with...as语句打开文件读取文件内容读取大文件的方式逐行读取和读取全部行写文件操作文件定位seek()tell()关闭文件文件管理获取目录结构获取当前目录切换当前所在目录创建目录删除目录删除文件重命名文件总结python精品专栏推荐python基础知识(0基础入门)python

Tomcat多实例+Nginx动静分离、负载均衡

这里写目录标题Tomcat多实例+动静分离、负载均衡一、Tomcat多实例部署1、安装JDK2、安装启动tomcat二、Nginx+Tomcat负载均衡、动静分离1、Nginx负载均衡实现原理1.1原理1.2Nginx配置反向代理的主要参数2、Nginx动静分离实现原理2.1原理2.2Nginx静态处理优势3、动静分离

计网第五章(运输层)(四)(TCP的流量控制)

一、基本概念流量控制就是指让发送方的发送速率不要太快,使得接收方来得及接收。可以使用滑动窗口机制在TCP连接上实现对发送方的流量控制。注意:之前在讨论可靠传输时,讨论过选择重传协议和回退N帧协议都是基于滑动窗口的机制上进行实现的。二、具体实现接收方通过向发送方发送带有自己接收窗口值的报文段来控制发送方的发送窗口。注意:

详解TCP/IP协议第五篇:详细介绍网络传输中的地址

文章目录一:通信中地址简介1:地址的唯一性(一):唯一性狭义概念(二):唯一性广义概念2:地址的层次性(一):地址分层的意义(二):MAC地址优劣(三):IP地址的便利一:通信中地址简介通信传输中,发送端和接收端可以被视为通信主体。它们都能由一个所谓“地址”的信息加以标识出来。当人们使用电话时,电话号码就相当于“地址”

中手游上半年扭亏为盈,仙剑IP魅力不减?

你也曾有过江湖梦吗?你也曾因“为国为民、为友为邻”的侠者心无处可安而苦恼吗?那么,“仙剑”系列游戏或许可以成为你的灵魂寄托之所。而能让侠者的江湖梦具象化的幕后厂商,便是中手游。两年前,中手游斥巨资买下了仙剑IP的大陆地区权益,两年内,中手游不断推出仙剑系列游戏新作。其中,公司于今年6月上线的《新仙剑奇侠传之挥剑问情》,

TCP特性的滑动窗口,流量控制

目录一、TCP特性滑动窗口二、TCP特性流量控制(作为滑动窗口的补充)一、TCP特性滑动窗口提高传输效率(更准确的说,让TCP在可靠传输的前提下,效率不太拉跨)💛当然你要是想让TCP媲美UDP,也是痴人说梦,只能说减小差距。一次性发一组数据,发数据的过程中,不需要等待ACK,就直接往前发,此时相当于“一份等待时间”等

TCP socket && UDP && TCP协议 && IP协议 && 以太网等

第1题(编程题)题目名称:编写TCP版本的echoserver和echoclient题目内容:编写TCP版本的echoserver和echoclient第2题(编程题)题目名称:编写TCP版本的字典客户端和字典服务器题目内容:编写TCP版本的字典客户端和字典服务器第3题(编程题)题目名称:编写TCP版本的多线程服务器题

02_Bootstrap基础组件02

4排版使用Bootstrap的排版特性,您可以创建标题、段落、列表及其他内联元素,实际上它是把大部分在HTML的基本标签加了样式。所以这部分相对比较简单。4.1标题h1-h6重新定义样式,HTML中的所有标题标签,<h1>到<h6>均可使用。增加了.h1到.h6类,为的是给内联(inline)属性的文本赋予标题的样式。

远程连接PostgreSQL:配置指南与安全建议

🌷🍁博主猫头虎(🐅🐾)带您GotoNewWorld✨🍁🐅🐾猫头虎建议程序员必备技术栈一览表📖:🛠️全栈技术FullStack:📚MERN/MEAN/MEVNStack|🌐Jamstack|🌍GraphQL|🔁RESTfulAPI|⚡WebSockets|🔄CI/CD|🌐Git&Versio

Linux安全加固:保护你的服务器

🌷🍁博主猫头虎(🐅🐾)带您GotoNewWorld✨🍁🦄博客首页——🐅🐾猫头虎的博客🎐🐳《面试题大全专栏》🦕文章图文并茂🦖生动形象🐅简单易学!欢迎大家来踩踩~🌺🌊《IDEA开发秘籍专栏》🐾学会IDEA常用操作,工作效率翻倍~💐🌊《100天精通Golang(基础入门篇)》🐅学会Gol

热文推荐