java添加多个水印
package com.zhx.util.imgutil; import com.zhx.util.stringutil.ArithUtil;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.filters.Watermark;
import net.coobird.thumbnailator.geometry.Positions;
import sun.font.FontDesignMetrics; import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator; public class ImgHandle { public static void main(String[] args) {
String filePath = "C:\\Users\\admin\\Desktop\\3333.jpg";
String newFilePath = "C:\\Users\\admin\\Desktop\\33d333ada1111.png";
// boolean sc2 = waterMarkWithText(filePath, newFilePath, "https://licd.beijing2022.cn", 1f, 1.0f, 1000, 1000, 1);
boolean sc23 = autoWaterMarkWithText(filePath, newFilePath, "licd.beijing2022.cn", 250, 250, 1.0f, 1);
} /**
* 图片缩放加水印
*
* @param filePath 原图路径
* @param newFilePath 处理后新图片路径
* @param waterMarkPath 水印图片路径
* @param scale 比例(0.1- 1.0)
* @param transparency 水印透明度
*/
public static boolean waterMark(String filePath, String newFilePath, String waterMarkPath, float scale, float transparency) {
try {
Thumbnails.of(filePath)
.scale(scale).
watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(waterMarkPath)), transparency).toFile(newFilePath);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
} /**
* 图片天加文字水印(默认缩小scale)
* 备注:
* Positions.BOTTOM_RIGHT 表示水印位置
*
* @param filePath 原图路径
* @param newFilePath 处理后新图片路径
* @param markText 水印文字
* @param scale 比例(0.1- 1.0)
* @param transparency 水印透明度
* @param type 1 按比例 2按宽高
* @param widthSize 缩放宽
* @param heightSize 缩放高
*/
public static boolean waterMarkWithText(String filePath, String newFilePath,
String markText, float scale, float transparency,
int widthSize, int heightSize, int type) {
try {
//先进行图片缩放
if (type == 1) {
imgScale(scale, filePath, newFilePath);
} else {
imgSize(widthSize, heightSize, filePath, newFilePath);
}
//获取缩放图分辨率
File file = new File(newFilePath);
BufferedImage imgBi = null;
try {
imgBi = ImageIO.read(file);
} catch (Exception e) {
e.printStackTrace();
}
//图片原始宽度
int width = imgBi.getWidth();
//图片原始高度
int height = imgBi.getHeight();
//计算右下角水印高宽
int waterWidth = new Double(width * 0.75).intValue();
int waterWidth2 = new Double(width * 0.5).intValue();
int waterHeight = new Double(height).intValue();
ImgHandle im = new ImgHandle();
String randomNum = "NO." + String.valueOf(System.currentTimeMillis());
if (randomNum.length() > 16) {
randomNum = randomNum.substring(0, 16);
}
BufferedImage bi = im.apply(imgBi, waterWidth, waterHeight, markText, 1, randomNum);
BufferedImage bi2 = im.apply(imgBi, waterWidth2, waterHeight, randomNum, 1, markText);
Watermark watermark = new Watermark(Positions.BOTTOM_LEFT,
bi, transparency);
Watermark watermark2 = new Watermark(Positions.BOTTOM_RIGHT,
bi2, transparency); Thumbnails.of(newFilePath).scale(1).
watermark(watermark).toFile(newFilePath);
watermark2(watermark2, newFilePath);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
} /**
* 生成的水印
*
* @param img
* @return
*/
public BufferedImage apply(BufferedImage img, int waterWidth, int waterHeight, String markText, float scale,
String markText2) {
int width = img.getWidth();
int height = img.getHeight(); BufferedImage imgWithWatermark = new BufferedImage(waterWidth, waterHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g = imgWithWatermark.createGraphics(); //设置透明 start
imgWithWatermark = g.getDeviceConfiguration().createCompatibleImage(waterWidth, waterHeight, Transparency.TRANSLUCENT);
g = imgWithWatermark.createGraphics();
g.setColor(new Color(159, 160, 160));
//设置透明 end
int[] sizes = new int[]{60, 30, 20, 16, 14, 9, 8, 6, 4};
int contentLength = 0;
Font font = null;
for (int i = 0; i < 8; i++) {
//设置字体及大小
font = new Font("Helvetica", Font.BOLD, sizes[i]);
g.setFont(font);
g.drawRect(0, 0, 0, 0);
contentLength = getWatermarkLength(markText + markText2, g);
if (contentLength < width) {
//找到最合适的字体
int contentLength2 = getWatermarkLength(markText, g);
// System.out.println("水印长度contentLength2----" + contentLength2);
break;
}
}
//设置水印的坐标
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(g.getFont());
int fontHeight = metrics.getHeight();
char[] data = markText.toCharArray();
//x1水印1距离左边距和底边距
//x2水印2距离右边距和底边距
int x1 = 0;
int x2 = 0;
if (width > 500) {
x1 = 20;
} else {
x1 = 8;
}
int y = waterHeight - x1;
// System.out.println("水印高度waterHeight----"+waterHeight);
// System.out.println("字体高度fontHeight----"+fontHeight);
x2 = width / 2 - getWatermarkLength(markText, g) - x1;
if (markText.contains("beijing2022")) {
// System.out.println("距离中心位置x1:----" + x1);
// System.out.println("距离顶部位置y:----" + y);
g.drawChars(data, 0, data.length, x1, y);
} else {
// System.out.println("距离中心位置x2:----" + x2);
// System.out.println("距离顶部位置y:----" + y);
g.drawChars(data, 0, data.length, x2, y);
}
return imgWithWatermark;
} /**
* 缩放
*
* @param scale
* @param filePath
* @param newFilePath
* @return
*/
public static boolean imgScale(float scale, String filePath, String newFilePath) {
try {
Thumbnails.of(filePath).scale(scale).toFile(newFilePath);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
} /**
* 大小缩放
*
* @param width
* @param height
* @param filePath
* @param newFilePath
* @return
*/
public static boolean imgSize(int width, int height, String filePath, String newFilePath) {
try {
Thumbnails.of(filePath).size(width, height).toFile(newFilePath);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
} public static boolean watermark2(Watermark watermark2, String filePath) {
try {
Thumbnails.of(filePath).scale(1).
watermark(watermark2).toFile(filePath);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
} /**
* 计算水印文字宽度
*
* @param waterMarkContent
* @param g
* @return
*/
public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
} /**
* @param filePath
* @param newFilePath
* @param markText
* @param minWidth 文件缩放宽
* @param minHeight 文件缩放高
* @param transparency
* @param addWater 是否用加水印1是2否
* @return
*/
public static boolean autoWaterMarkWithText(String filePath, String newFilePath, String markText, int minWidth, int minHeight, float transparency, int addWater) {
String fileP = filePath;
try {
//获取原图分辨率
//https://www.cnblogs.com/SimonHu1993/p/9396375.html
RotateImage.RotateImg(filePath, newFilePath);
fileP = newFilePath;
} catch (Exception e) {
e.printStackTrace();
}
File file = new File(fileP);
BufferedImage imgBi = null;
try {
imgBi = ImageIO.read(file);
} catch (Exception e) {
e.printStackTrace();
}
// 图片原始宽度
int width = imgBi.getWidth();
int height = imgBi.getHeight();
double min = ArithUtil.getDouble(String.valueOf(minWidth));
double real = ArithUtil.getDouble(String.valueOf(width));
float scale = (float) ArithUtil.div(min, real, 5);
//缩放规则1 按比例 2按宽高
int type = 1;
if (minWidth != 0 && minHeight != 0) {
type = 2;
//如果按比例缩放的高度大于要求高度再缩放高
double realHeight = ArithUtil.getDouble(String.valueOf(height));
float afterHeight = (float) ArithUtil.mul(realHeight, scale);
if (afterHeight > minHeight) {
float scale2 = (float) ArithUtil.div(minHeight, afterHeight, 5);
minWidth = new Double(minWidth * scale2).intValue();
afterHeight = minHeight;
}
minHeight = (int) afterHeight;
}
Boolean result = false;
//最大的缩略图上加水印,其他的缩略图在加完水印的缩略图上进行压缩
if (addWater == 1) {
result = waterMarkWithText(fileP, newFilePath, markText, scale, transparency,
minWidth, minHeight, type);
} else if (addWater == 2) {
result = imgSize(minWidth, minHeight, fileP, newFilePath);
}
return result;
} /**
* 图片缩放
*
* @param filePath 图片路径
* @param newFilePath 缩略图路径
* @param scale 比例(0.1- 1.0)
* @return
*/
public static boolean scaleImg(String filePath, String newFilePath, float scale) {
try {
Thumbnails.of(filePath).scale(scale).toFile(newFilePath);
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
} /**
* 获得图片的格式,例如:JPEG、GIF等
*
* @param file
* @return
*/
public static String getImageFormat(File file) {
try {
ImageInputStream iis = ImageIO.createImageInputStream(file);
Iterator<ImageReader> iterator = ImageIO.getImageReaders(iis);
while (iterator.hasNext()) {
ImageReader reader = iterator.next();
return reader.getFormatName().toLowerCase();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
} }
贴上横竖效果图:


java添加多个水印的更多相关文章
- Java 添加Word文本水印、图片水印
水印是一种常用于各种文档的声明.防伪手段,一般可设置文字水印或者加载图片作为水印.以下内容将分享通过Java编程给Word文档添加水印效果的方法,即 文本水印 图片水印 使用工具:Free Spire ...
- JAVA实用案例之水印开发
写在最前面 上周零零碎碎花了一周的时间研究水印的开发,现在终于写了个入门级的Demo,做下笔记同时分享出来供大家参考. Demo是在我上次写的 JAVA实用案例之文件导入导出(POI方式) 框架基础上 ...
- Windows操作 - Photoshop为图片添加透明立体水印
原文地址:http://design.yesky.com/photoshop/252/2427752.shtml 本文我们介绍用Photoshop为图片添加透明立体水印的方法和技巧. 原图: 打开原图 ...
- Java添加事件的四种方式
Java添加事件的几种方式(转载了codebrother的文章,做了稍微的改动) /** * Java事件监听处理——自身类实现ActionListener接口,作为事件监听器 * * @author ...
- Java图片加文字水印
Java图片加文字水印 import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.I ...
- PS添加透明立体水印
PS: CS2 本文我们介绍用Photoshop为图片添加透明立体水印的方法和技巧. 原图: Duplicate Layer,并输入文字: 设置Layer->Layer Style->Be ...
- Java 添加、验证PDF 数字签名
在设置文档内容保护的方法中,除了对文档加密.添加水印外,应用数字签名也是一种有效防伪手段.数字签名的文件比较容易验证,并且具有较高的权威性和可信度.在PDF文档中,有可直接添加或验证数字签名的功能方法 ...
- java添加对象成功后想知道当前添加对象的id
我使用的是springboot Mybatis写的项目,结构如下 mapper.xml(以下2个属性必须要有,主键id 一般是自动生成的) mapper.java (注意新增的返回值不需要,一般情况 ...
- 视频特效制作:如何给视频添加边框、水印、动画以及3D效果
2014-12-08 09:47 编辑: suiling 分类:iOS开发 来源:叶孤城的blog 招聘信息: iOS手机软件开发工程师 iOS工程师 Web后端高级开发工程师 iOS软件工程师 ja ...
随机推荐
- PL/SQL设置
PL/SQL 自定义快捷键(比如输入s,直接就显示select * from) 1.1 修改Code assistant快捷键tools->preferences->User Interf ...
- 为什么在移动端用rem圆角不圆
rem是根据网页效果图的尺寸来计算的,当然还要借助媒体查询来完成.例如你的设计稿如果是宽720px的话,那你的文字就要以原始大小除以11.25,就是对应下面媒体查询720px:例如16px的话就要16 ...
- python并发编程之进程池,线程池,协程
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- LeetCode(120):三角形最小路径和
Medium! 题目描述: 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] ...
- 【python】confluent_kafka将offset置为最大
该博文方法有问题,正确方案在http://www.cnblogs.com/dplearning/p/7992994.html 将指定group对应的offset重置到最大值,跳过未消费数据 代码如下: ...
- Python基础之面向对象的软件开发思路
当我们来到生产环境中的时候,对一个软件需要开发的时候,刚开始也可能会懵逼,挝耳挠腮.不知从何下手,其 实,大家也不要苦恼,这是大多数程序员都会遇到的问题.那么,我们就要想一想了,既然大家都会这样,到低 ...
- poj3107树的重心
/*树的重心求法:两次dfs,第一次dfs处理出每个结点的size,以此求每个结点大儿子的size,第二次dfs将每个结点大儿子的size和余下结点数进行比较,所有结点里两个值之间差值最小的那个点就是 ...
- 改变html结构可以实现优先加载
我们通过一个实例来看一下: 本编程题目,完成一个混合布局的编写吧!最终效果如下图: 任务 任务1:完成顶部(top).底部(foot)宽度自适应 任务2:中间分为2两栏,其中,左侧(left)宽度为2 ...
- mysql常见安全加固策略
原创 2017年01月17日 21:36:50 标签: 数据库 / mysql / 安全加固 5760 常见Mysql配置文件:linux系统下是my.conf,windows环境下是my.ini: ...
- 步步为营-104-Lambda语句
1:Lambda的拼接 首先借助一个Lambda的帮助类 using System; using System.Collections.Generic; using System.Linq; usin ...