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

news2024/11/15 17:48:40

文章目录

  • 1 添加文字水印、图片水印
    • 1.1 给图片添加文字水印
      • 1.1.1 获取原图片对象信息
        • 1.1.1.1 读取本地图片
        • 1.1.1.2 读取网络图片
      • 1.1.2 添加水印
      • 1.1.3 确定水印位置
        • 1.1.3.1 设置固定值
        • 1.1.3.2 根据原图大小进行设置
      • 1.1.4 获取目标图片
      • 1.1.5 完整代码
    • 1.2 java实现给图片添加图片水印
      • 1.2.1 添加图片水印方法
      • 1.2.2 完整代码

1 添加文字水印、图片水印

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

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

1.1 给图片添加文字水印

1.1.1 获取原图片对象信息

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

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

在这里插入图片描述

通过代码实现读取本地目录(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);
1.1.1.2 读取网络图片
//创建一个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);

1.1.2 添加水印

通过上面的步骤,我们已经获取到了原始图片信息,下面需要创建一个画笔进行水印的添加。水印包含文字水印、图片水印。

画笔可以设置水印颜色、字体大小、字体样式等。

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;
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();

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(磅),数字越大,字就越大
需要注意是 水印坐标位置。设置不当,就看不到水印效果。

1.1.3 确定水印位置

1.1.3.1 设置固定值

首先,我们要知道图片上的坐标的表示法。具体如下:

图片
将图片保存到本地,然后选中图片点击右键,编辑,选择画图软件打开

图片
将鼠标移动到想要添加水印的位置,左下角可以看到鼠标点击位置对应的坐标值,拿到这个坐标值写入程序即可
在这里插入图片描述

1.1.3.2 根据原图大小进行设置

根据原图大小进行设置,如放置在原图的中间位置

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

1.1.4 获取目标图片

经过上面的操作后,我们的图片添加文字就已经处理完成了。但现在还保存在Java对象中。

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

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

1.1.5 完整代码

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;

/**
 * 图片添加水印
 * @author qzz
 */
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());
    }
}

1.2 java实现给图片添加图片水印

下载水印图片到本地:
水印图片位置:F:\image\s.png

1.2.1 添加图片水印方法

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

1.2.2 完整代码

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;

/**
 * 图片添加水印
 * @author qzz
 */
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());
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1078855.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HomeView/主页 的实现

1. 创建数据模型 1.1 创建货币模型 CoinModel.swift import Foundation// GoinGecko API info /*URL:https://api.coingecko.com/api/v3/coins/markets?vs_currencyusd&ordermarket_cap_desc&per_page250&page1&sparklinetrue&price_change_percentage24…

论文中的小细节——为什么论文中总是写WX而不是XW?

这是最近一个师弟问我的问题,为什么在论文里面总是写的 Y W X YWX YWX,而不是 Y X W YXW YXW?就算有的时候需要转置 W W W 或者 X X X,都不写 Y X W YXW YXW? 这个问题我最开始回答的是这就是约定俗成的写法&…

新能源三电系统测试如何快速连接,避免多次插拔?安规测试电连接器的作用

新能源汽车行业高速发展,电机、电动、电池作为核心三部件,必须有严格的检测已确保产品性能、质量、安全性符合要求。其中会涉及多种测试,如:防水防尘/气密测试、EOL测试、DCR测试等,需要连接相应的检测设备仪器。如何快…

LLaVA:大型语言和视觉助手,图片识别和理解能力让人惊叹

01简介 视觉指令调整:针对多模式 GPT-4 级别功能而构建的大型语言和视觉助手。 视觉聊天:构建多模式 GPT-4 级聊天机器人构建了包含 30 个未见过的图像的评估数据集:每个图像都与三种类型的指令相关联:对话、详细描述和…

查找浏览器中保存的密码

edge浏览器 谷歌浏览器 设置-》自动填充密码-》点击密码管理工具 后就可以查看到浏览器保存的密码了

PyTorch 入门

一、说明 深度学习是机器学习的一个分支,其中编写的算法模仿人脑的功能。深度学习中最常用的库是 Tensorflow 和 PyTorch。由于有各种可用的深度学习框架,人们可能想知道何时使用 PyTorch。以下是人们更喜欢使用 Pytorch 来完成特定任务的原因。 Pytorch…

LeetCode918 环形子数组最大值

这里写自定义目录标题 题目: 思路: 1、破环成链。 由于是环形数组,则数组的末端会与开头相连呈环状。 只需要将长度为N的数组拷贝一次,拼接在原数组后,即得到长度为2N的数组,该数组即为环形数组。 如&am…

mars3d的api文档关于addDynamicPosition查找使用说明

示例链接:功能示例(Vue版) | Mars3D三维可视化平台 | 火星科技 api地址:Mars3D三维可视化平台 | 火星科技 说明: 1.用户反馈不知道如何搜索这个属性的用法 说明: 1. 示例代码中的graphic.addDynamicPosition()说明这个addDynam…

electron 升级 v22 遇到问题

Electron 漏洞 https://mp.weixin.qq.com/s/5LpSJb_5uV8EIDOl3fz9Tw 由于 23以上不在支持win 7 8 8.1 所以我选择安装 v22.3.24 electron 22.3.24 node-sass 6.0.1 sass-loader 10.4.1 对应的版本 npm i node-sass6.0.1 --sass_binary_sitehttps://npm.taobao.org/mirrors…

vscode安装svn扩展(windows)

一、安装 1.1 环境说明 操作系统 windows 10 1.2 安装过程 1. 安装svn 双击安装程序 点击next 继续next 继续next 点击Install 在弹出框中点击 是 开始安装进度,一会将安装成功 安装结束 右键菜单栏中已经有svn选项,并且能正常拉取以…

一区TOP期刊提出一种植被覆盖度估算新方法

研究背景:光合植被(PV)主要指绿色的叶片,而非光合植被(NPV)包括凋落物和茎等。利用遥感数据估算植被覆盖(FVC)主要有三种方法:1) 回归模型2)光谱混合物分析(SMA) 3) 数据驱动的模型。在这三种方法中,回归模型因其简单性…

网络安全--APT技术、密码学

目录 1. 什么是APT? 2. APT 的攻击过程? 3. 详细说明APT的防御技术 4. 什么是对称加密? 5. 什么是非对称加密? 6. 私密性的密码学应用? 7. 非对称加密如何解决身份认证问题? 8. 如何解决公钥身份认…

这篇被吹爆了的职称评审个人专业技术业务工作总结范文模板,不看就是你的损失了

职称评审需要写个人工作总结吗?甘建二告诉你毫无疑问,肯定是必须要的,对于评职称的人来说,准备一篇几千字的工作技术总结,是必不可少的申报材料之一。甚至对于初级职称评审来说,个人专业技术总结决定了一个…

三战时区问题

一、前言 前两天测试向我反馈生产环境挖机进口日期页面上展示的比数据库中存储的早了一天,但在测试环境是正常的,并且其它时间字段都没有任何问题,很是奇怪,安排开发排查没有头绪,然后我自己登录生产环境确认LInux系统…

别再瞎考证了,从事网络安全工作,这五大证书是加分项!

其他行业,对证书的要求可能并不明显,但在信息安全类的岗位中,大部分招聘信息中明确标明持有NISP、CISP等网络安全相关资质证书优先等。因此想要快速进入网络安全行业,通过学习并考取相关证书,是一个很不错的途径。 那么…

flutter开发实战-Universal Links配置及flutter微信分享实现

flutter开发实战-Universal Links配置及flutter微信分享实现 在最近开发中碰到了需要实现微信分享,在iOS端需要配置UniversalLink,在分享使用fluwx插件来实现微信分享功能。 一、配置UniversalLink 1.1、什么是UniversalLink Universal link 是Apple…

Vue中的router路由的介绍(快速入门)

路由的介绍 文章目录 路由的介绍1、VueRouter的介绍2、VueRouter的使用(52)2.1、5个基础步骤(固定)2.2、两个核心步骤 3、组件存放的目录(组件分类) 生活中的路由:设备和ip的映射关系(路由器) V…

管网水位监测仪:井下水位监测的创新者

随着城市化进程的不断推进,城市排水管网系统的完善和安全运行越来越受到社会和政府的关注。近期,国家加大了对城市基础设施建设的投入力度,推动了排水管网系统的升级和改造。在这样的背景下,万宾科技推出了一款全新的产品——管网…

canvas力导布局

老规矩&#xff0c;先上效果图 <html><head><style>* {margin: 0;padding: 0;}canvas {display: block;width: 100%;height: 100%;background: #000;}</style> </head><body><canvas id"network"></canvas> </…

1600*C. k-Tree(DP)

Problem - 431C - Codeforces 解析&#xff1a; #include<bits/stdc.h> using namespace std; #define int long long const int mod1e97,N110; int n,k,d,dp[N][2]; signed main(){scanf("%lld%lld%lld",&n,&k,&d);dp[0][0]1;for(int i1;i<n;…