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. swift 学习- 11 -- 属性

    // '属性'将值跟特定的类, 结构体或枚举关联, 存储属性常量或变量作为实例的一部分,而计算属性计算(不是存储) 一个值, 计算属性可以用于 类, 结构体, 枚举, 存储属性只能用于 类 和 结构体 ...

  2. C语言学习及应用笔记之三:C语言const关键字及其使用

    在C语言程序中,const关键字也是经常会用到的一个关键字,那么使用const关键字的目的是什么呢?事实上,在程序中使用const关键字的主要目的就是为了向使用者传递设计者的一些意图. 事实上,无论我 ...

  3. Java的家庭记账本程序(D)

    日期:2019.2.8 博客期:031 星期一 今天是把程序的查询功能以列表的形式完成了! 截图如下:

  4. python自动化-unittest批量执行用例(discover)

    前言 我们在写用例的时候,单个脚本的用例好执行,那么多个脚本的时候,如何批量执行呢?这时候就需要用到unittet里面的discover方法来加载用例了. 加载用例后,用unittest里面的Text ...

  5. angularjs 监听 文档click 事件

    项目 上遇到  innHTML  放入 一大段的html 内容 中带有 click 事件 如onclick="callInMethod("http://www.crm.bmcc.c ...

  6. 第七篇 python基础之函数,递归,内置函数

    一 数学定义的函数与python中的函数 初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因 ...

  7. Python安装、卸载第三方模块

    pip command ModuleName command:用于指定要执行的命令(install:安装,uninstall:卸载) ModuleName:需要安装的模块名称 示例: 安装第三方模块n ...

  8. HTTP协议请求头信息和响应头信息

    阅读目录 http的请求部分 常用请头信息 常用响应头信息 http的请求部分 基本结构 请求行 GET  /test/hello.html HTTP/1.1 消息头(并不是每一次请求都一样) 空行 ...

  9. python列表1

    List (列表)List(列表) 是 Python 中使用最 频繁的数据类 型.列表 可以 完成大 多数集 合类 的数据 结构 实现. 列表中 元素 的类型 可以 不相同 ,它支 持数 字,字 符串 ...

  10. lsattr chattr 文件安全设置

    [root@test_android_client_download xianlaigames]# lsattr -------------e- ./jilinmj.apk[root@test_and ...