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添加多个水印的更多相关文章

  1. Java 添加Word文本水印、图片水印

    水印是一种常用于各种文档的声明.防伪手段,一般可设置文字水印或者加载图片作为水印.以下内容将分享通过Java编程给Word文档添加水印效果的方法,即 文本水印 图片水印 使用工具:Free Spire ...

  2. JAVA实用案例之水印开发

    写在最前面 上周零零碎碎花了一周的时间研究水印的开发,现在终于写了个入门级的Demo,做下笔记同时分享出来供大家参考. Demo是在我上次写的 JAVA实用案例之文件导入导出(POI方式) 框架基础上 ...

  3. Windows操作 - Photoshop为图片添加透明立体水印

    原文地址:http://design.yesky.com/photoshop/252/2427752.shtml 本文我们介绍用Photoshop为图片添加透明立体水印的方法和技巧. 原图: 打开原图 ...

  4. Java添加事件的四种方式

    Java添加事件的几种方式(转载了codebrother的文章,做了稍微的改动) /** * Java事件监听处理——自身类实现ActionListener接口,作为事件监听器 * * @author ...

  5. Java图片加文字水印

    Java图片加文字水印 import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.I ...

  6. PS添加透明立体水印

    PS: CS2 本文我们介绍用Photoshop为图片添加透明立体水印的方法和技巧. 原图: Duplicate Layer,并输入文字: 设置Layer->Layer Style->Be ...

  7. Java 添加、验证PDF 数字签名

    在设置文档内容保护的方法中,除了对文档加密.添加水印外,应用数字签名也是一种有效防伪手段.数字签名的文件比较容易验证,并且具有较高的权威性和可信度.在PDF文档中,有可直接添加或验证数字签名的功能方法 ...

  8. java添加对象成功后想知道当前添加对象的id

    我使用的是springboot Mybatis写的项目,结构如下 mapper.xml(以下2个属性必须要有,主键id 一般是自动生成的) mapper.java  (注意新增的返回值不需要,一般情况 ...

  9. 视频特效制作:如何给视频添加边框、水印、动画以及3D效果

    2014-12-08 09:47 编辑: suiling 分类:iOS开发 来源:叶孤城的blog 招聘信息: iOS手机软件开发工程师 iOS工程师 Web后端高级开发工程师 iOS软件工程师 ja ...

随机推荐

  1. PL/SQL设置

    PL/SQL 自定义快捷键(比如输入s,直接就显示select * from) 1.1 修改Code assistant快捷键tools->preferences->User Interf ...

  2. 为什么在移动端用rem圆角不圆

    rem是根据网页效果图的尺寸来计算的,当然还要借助媒体查询来完成.例如你的设计稿如果是宽720px的话,那你的文字就要以原始大小除以11.25,就是对应下面媒体查询720px:例如16px的话就要16 ...

  3. python并发编程之进程池,线程池,协程

    需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...

  4. LeetCode(120):三角形最小路径和

    Medium! 题目描述: 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] ...

  5. 【python】confluent_kafka将offset置为最大

    该博文方法有问题,正确方案在http://www.cnblogs.com/dplearning/p/7992994.html 将指定group对应的offset重置到最大值,跳过未消费数据 代码如下: ...

  6. Python基础之面向对象的软件开发思路

    当我们来到生产环境中的时候,对一个软件需要开发的时候,刚开始也可能会懵逼,挝耳挠腮.不知从何下手,其 实,大家也不要苦恼,这是大多数程序员都会遇到的问题.那么,我们就要想一想了,既然大家都会这样,到低 ...

  7. poj3107树的重心

    /*树的重心求法:两次dfs,第一次dfs处理出每个结点的size,以此求每个结点大儿子的size,第二次dfs将每个结点大儿子的size和余下结点数进行比较,所有结点里两个值之间差值最小的那个点就是 ...

  8. 改变html结构可以实现优先加载

    我们通过一个实例来看一下: 本编程题目,完成一个混合布局的编写吧!最终效果如下图: 任务 任务1:完成顶部(top).底部(foot)宽度自适应 任务2:中间分为2两栏,其中,左侧(left)宽度为2 ...

  9. mysql常见安全加固策略

    原创 2017年01月17日 21:36:50 标签: 数据库 / mysql / 安全加固 5760 常见Mysql配置文件:linux系统下是my.conf,windows环境下是my.ini: ...

  10. 步步为营-104-Lambda语句

    1:Lambda的拼接 首先借助一个Lambda的帮助类 using System; using System.Collections.Generic; using System.Linq; usin ...