java水印工具类在请看上面的立即下载
转载请注明出处,谢谢
ImageUtil类代码,使用时调用 markerText 方法就行
import com.sysfunc.core.mybatisplus.exception.BizException;
import com.sysfunc.yyt.cms.dto.FileVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.logging.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Base64;
import java.util.List;
public class ImageUtil {
/**
* 给图片添加文字水印
* @param waterMarkContents 水印文字(一个集合一个值对应一条水印)
* @param buffin 源图像输入流
* @param fileSuffix 文件后缀名
* @param fontSize 水印字体大小
* @param color 水印的字体颜色
* @param alpha 水印透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
* @return byte[]
*/
public static byte[] markerText(List<String> waterMarkContents, InputStream buffin, String fileSuffix, int fontSize, Color color, float alpha) {
if (buffin == null) {
return null;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
// 水印之间的横向间隔
int xmove = 100;
// 水印之间的纵向间隔
int ymove = 100;
Image srcImg = ImageIO.read(buffin);//文件转化为图片
int srcImgWidth = srcImg.getWidth(null);//获取图片的宽
int srcImgHeight = srcImg.getHeight(null);//获取图片的高
// 根据图片高度决定水印文字大小,文字间隔
if (srcImgHeight <= 500 && srcImgWidth <= 500) {
fontSize = 20;
xmove = 50;
ymove = 50;
} else if (srcImgHeight > 500 && srcImgHeight <= 1000 && srcImgWidth > 500 && srcImgWidth <= 1000) {
fontSize = 28;
} else if (srcImgHeight > 1000 && srcImgHeight <= 2000 && srcImgWidth > 1000 && srcImgWidth <= 2000) {
fontSize = 50;
xmove = 150;
ymove = 150;
} else if (srcImgHeight > 2000 && srcImgWidth > 2000) {
fontSize = 95;
xmove = 300;
ymove = 300;
}
if (srcImgHeight > 3000 && srcImgWidth > 3000) {
fontSize = 135;
xmove = 400;
ymove = 400;
}
Font font = new Font("宋体", Font.BOLD, fontSize);
// 获取其中最长的文字水印的大小
int maxLen = 0;
int maxHigh = 0;
for (int i = 0; i < waterMarkContents.size(); i++) {
String waterMarkContent = waterMarkContents.get(i);
int fontlen = getStringLength(font, waterMarkContent);
if (fontlen >= maxLen) {
maxLen = fontlen;
}
maxHigh = maxHigh + (i + 1) * fontSize + 10;
}
//一个div 每行每列的打印到图片 上
int rowsNumber = 15;// 图片的高 除以 文字水印的宽 打印的行数(以文字水印的宽为间隔)
int columnsNumber = 15;//图片的宽 除以 文字水印的宽 每行打印的列数(以文字水印的宽为间隔)
// 加水印
BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bufImg.createGraphics();//得到画笔
g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
g.setColor(color); //设置水印颜色
g.setFont(font);//设置字体
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));//设置水印文字透明度
g.rotate(Math.toRadians(-45), srcImgWidth, srcImgHeight);//设置水印旋转
//至少打印一次
if (rowsNumber < 1) {
rowsNumber = 1;
}
if (columnsNumber < 1) {
columnsNumber = 1;
}
int yz = 0;
//遍历每行打印到图片上的个数
for (int a = 0; a < rowsNumber; a++) {
int t = 0;
for (int j = 0; j < waterMarkContents.size(); j++) {
String waterMarkContent = waterMarkContents.get(j);
int y = (j + 1) * 40 + 10 + t;
// 文字叠加,自动换行叠加,注意符号
int tempX = 10;
int tempY = (-srcImgHeight / 2) - 150 + y + yz;
// 单字符长度
int tempCharLen = 0;
// 单行字符总长度临时计算
int tempLineLen = 0;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < waterMarkContent.length(); i++) {
char tempChar = waterMarkContent.charAt(i);
tempCharLen = getCharLen(tempChar, g);
tempLineLen += tempCharLen;
// 和图片的长度进行对应的比较操作
if (tempLineLen >= srcImgWidth) {
// 长度已经满一行,进行文字叠加
g.drawString(sb.toString(), tempX, tempY);
t = t + 40;
// 清空内容,重新追加
sb.delete(0, sb.length());
tempY += 40;
tempLineLen = 0;
}
// 追加字符
sb.append(tempChar);
}
// 遍历每列打印到图片上的个数
for (int z = 0; z < columnsNumber; z++) {
// 最后叠加余下的文字
g.drawString(sb.toString(), tempX, tempY);
tempX = tempX + maxLen + xmove;
}
}
yz = yz + maxHigh + ymove;
}
g.dispose();// 释放资源
ImageIO.write(bufImg, fileSuffix, outputStream);
} catch (Exception e) {
e.printStackTrace();
e.getMessage();
}
return outputStream.toByteArray();
}
public static int getCharLen(char c, Graphics2D g) {
return g.getFontMetrics(g.getFont()).charWidth(c);
}
//得到字符串长度
public static int getStringLength(Font font, String markContent) {
if (StringUtils.isEmpty(markContent)) {
return 0;
}
if (null == font) {
font = new Font(null);
}
JLabel label = new JLabel(markContent);
FontMetrics metrics = label.getFontMetrics(font);
int width = metrics.stringWidth(label.getText());//文字水印的宽
return width;
}
}
返回的是byte []字节数组,要生成图片可以参考下面方法
// bytes 图片字节数组,path 保存路径
public static boolean byteEncryptFile(byte [] bytes, String path) {
// 图像数据为空
if (bytes == null) {
return false;
}
if(path == null || StringUtils.isEmpty(path)){
return false;
}
try {
createFileParentDir(path, 0);
} catch (Exception e) {
System.out.println("创建文件目录失败");
}
OutputStream out = null;
try {
out = new FileOutputStream(path);
out.write(bytes);
out.flush();
return true;
} catch (Exception e) {
System.out.println("保存图片失败");
}finally {
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
// 创建文件路径
public static void createFileParentDir(String imgFilePath, Integer num) {
try {
File dirFile = new File(imgFilePath);
if(!dirFile.getParentFile().exists()
&& !dirFile.getParentFile().mkdirs()){
System.out.println("创建文件目录失败!");
}
} catch (Exception e) {
if (num < 2) {
num++;
createFileParentDir(imgFilePath, num);
} else {
throw e;
}
}
}
增加水印后的图片,文件大小会比原来的大一点,图片压缩可以参考我另一篇文章
码字不易,于你有利,勿忘点赞
北国风光,千里冰封,万里雪飘