现阶段需要实现图片导出添加水印的内容,查询资料总结了如下的图片导出加水印工具类,分享给大家
一、工具类公共参数
public class WaterMarkUtils {
private static final int XMOVE = 80;//满屏水印中水印之间的横向间隔
private static final int YMOVE = 80;//满屏水印中水印之间的纵向间隔
private static Color color = Color.red;//水印文字颜色
private static int positionWidth = 150;//单个水印中水印横向位置
private static int positionHeight = 300;//单个水印中水印纵向位置
public int getCharLen(char c, Graphics2D g) {
return g.getFontMetrics(g.getFont()).charWidth(c);
}
/**
* 获取水印文字总长度
*
* @paramwaterMarkContent水印的文字
* @paramg
* @return水印文字总长度
*/
public int getWatermarkLength(String waterMarkContent, Graphics2D g) {
return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
}
}
二、图片添加满屏水印后保存到固定地址
/**
* 满屏水印 保存路径
*
* @param srcImgPath 需要添加水印的图片的路径
* @param outImgPath 添加水印后图片输出路径
* @param waterMarkContent 水印的文字,多排水印请使用"||"分割
*/
@SneakyThrows
public void waterPress(String srcImgPath, String outImgPath, String waterMarkContent) {
FileOutputStream outImgStream = null;
try {
String[] waterMarkContents = waterMarkContent.split("\\|\\|");
// 读取原图片信息
File srcImgFile = new File(srcImgPath);
Image srcImg = ImageIO.read(srcImgFile);
// 原图宽度
int srcImgWidth = srcImg.getWidth(null);
//以图片宽度为度量,设置对应的字体大小
int fontSize;
if (srcImgWidth <= 3000) fontSize = 30;
else fontSize = (int) (srcImgWidth * 0.01);
// 原图高度
int srcImgHeight = srcImg.getHeight(null);
// 加水印
BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
// 得到画笔对象
Graphics2D g = bufImg.createGraphics();
g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
// Font font = new Font("Courier New", Font.PLAIN, 12);
// 字体
Font font = new Font("宋体", Font.PLAIN, fontSize);
// 根据图片的背景设置水印颜色
g.setColor(color);
// 设置水印文字字体
g.setFont(font);
// 设置水印旋转
g.rotate(Math.toRadians(-45), (double) bufImg.getWidth() / 2, (double) bufImg.getHeight() / 2);
// 获取其中最长的文字水印的大小
int maxLen = 0;
int maxHigh = 0;
for (int i = 0; i < waterMarkContents.length; i++) {
waterMarkContent = waterMarkContents[i];
int fontlen = getWatermarkLength(waterMarkContent, g);
if (fontlen >= maxLen) {
maxLen = fontlen;
}
maxHigh = maxHigh + (i + 1) * fontSize + 10;
break;
}
// 文字长度相对于图片宽度应该有多少行
int line = srcImgWidth * 2 / maxLen;
int co = srcImgHeight * 2 / maxHigh;
int yz = 0;
// 填充Y轴方向
for (int a = 0; a < co; a++) {
int t = 0;
for (int j = 0; j < waterMarkContents.length; j++) {
waterMarkContent = waterMarkContents[j];
int y = (j + 1) * fontSize + 10 + t;
// 文字叠加,自动换行叠加,注意符号
int tempX = -srcImgWidth / 2;
int tempY = -srcImgHeight / 2 + 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 + fontSize;
// 清空内容,重新追加
sb.delete(0, sb.length());
tempY += fontSize;
tempLineLen = 0;
}
// 追加字符
sb.append(tempChar);
}
// 填充X轴
for (int z = 0; z < line; z++) {
// 最后叠加余下的文字
g.drawString(sb.toString(), tempX, tempY);
tempX = tempX + maxLen + XMOVE;
}
}
yz = yz + maxHigh + YMOVE;
}
g.dispose();
// 输出图片
outImgStream = new FileOutputStream(outImgPath);
ImageIO.write(bufImg, "jpg", outImgStream);
System.out.println("操作成功");
return;
} catch (Exception e) {
e.printStackTrace();
} finally {
outImgStream.flush();
outImgStream.close();
}
}
三、图片添加满屏水印后以输出流输出
/**
* 满屏水印 输出流
*
* @param srcImgPath 需要添加水印的图片的路径
* @param os 输出流
* @param waterMarkContent 水印的文字,多排水印请使用"||"分割
**/
@SneakyThrows
public void waterPress(String srcImgPath, OutputStream os, String waterMarkContent) {
try {
String[] waterMarkContents = waterMarkContent.split("\\|\\|");
// 读取原图片信息
File srcImgFile = new File(srcImgPath);
Image srcImg = ImageIO.read(srcImgFile);
// 原图宽度
int srcImgWidth = srcImg.getWidth(null);
//以图片宽度为度量,设置对应的字体大小
int fontSize;
if (srcImgWidth <= 3000) fontSize = 30;
else fontSize = (int) (srcImgWidth * 0.01);
// 原图高度
int srcImgHeight = srcImg.getHeight(null);
// 加水印
BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
// 得到画笔对象
Graphics2D g = bufImg.createGraphics();
g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
// Font font = new Font("Courier New", Font.PLAIN, 12);
// 字体
Font font = new Font("宋体", Font.PLAIN, fontSize);
// 根据图片的背景设置水印颜色
g.setColor(color);
// 设置水印文字字体
g.setFont(font);
// 设置水印旋转
g.rotate(Math.toRadians(-45), (double) bufImg.getWidth() / 2, (double) bufImg.getHeight() / 2);
// 获取其中最长的文字水印的大小
int maxLen = 0;
int maxHigh = 0;
for (int i = 0; i < waterMarkContents.length; i++) {
waterMarkContent = waterMarkContents[i];
int fontlen = getWatermarkLength(waterMarkContent, g);
if (fontlen >= maxLen) {
maxLen = fontlen;
}
maxHigh = maxHigh + (i + 1) * fontSize + 10;
break;
}
// 文字长度相对于图片宽度应该有多少行
int line = srcImgWidth * 2 / maxLen;
int co = srcImgHeight * 2 / maxHigh;
int yz = 0;
// 填充Y轴方向
for (int a = 0; a < co; a++) {
int t = 0;
for (int j = 0; j < waterMarkContents.length; j++) {
waterMarkContent = waterMarkContents[j];
int y = (j + 1) * fontSize + 10 + t;
// 文字叠加,自动换行叠加,注意符号
int tempX = -srcImgWidth / 2;
int tempY = -srcImgHeight / 2 + 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 + fontSize;
// 清空内容,重新追加
sb.delete(0, sb.length());
tempY += fontSize;
tempLineLen = 0;
}
// 追加字符
sb.append(tempChar);
}
// 填充X轴
for (int z = 0; z < line; z++) {
// 最后叠加余下的文字
g.drawString(sb.toString(), tempX, tempY);
tempX = tempX + maxLen + XMOVE;
}
}
yz = yz + maxHigh + YMOVE;
}
g.dispose();
ImageIO.write(bufImg, "jpg", os);
System.out.println("操作成功");
return;
} catch (Exception e) {
e.printStackTrace();
} finally {
os.flush();
os.close();
}
}
四、图片左上角添加单个水印
/**
* 图片加单个水印
*
* @param waterMarkContent 水印文字
* @param srcImgPath 源文件路径
* @param os 输出流
* @param degree 设置角度
*/
public static void waterPressOneText(String waterMarkContent, String srcImgPath, OutputStream os, Integer degree) {
InputStream is = null;
try {
//1、源图片
Image srcImg = ImageIO.read(new File(srcImgPath));
BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
//2、得到画笔对象
Graphics2D g = buffImg.createGraphics();
//3、设置对线段的锯齿状边缘处理
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(
srcImg.getScaledInstance(srcImg.getWidth(null),
srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0, null);
//4、设置水印旋转
if (null != degree) {
g.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);
}
// 原图宽度
int srcImgWidth = srcImg.getWidth(null);
//以图片宽度为度量,设置对应的字体大小
int fontSize;
if (srcImgWidth <= 3000) fontSize = 50;
else fontSize = (int) (srcImgWidth * 0.05);
//5、设置水印文字颜色
g.setColor(color);
//6、设置水印文字Font
Font font = new Font("宋体", Font.PLAIN, fontSize);
g.setFont(font);
//7、设置水印文字透明度
// g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5F));
//8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
g.drawString(waterMarkContent, positionWidth, positionHeight);//9、释放资源
g.dispose();//10、生成图片
ImageIO.write(buffImg, "JPG", os);
System.out.println("图片完成添加水印文字");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != is)
is.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
if (null != os)
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
五、图片中间添加单个斜对角水印
/**
* 图片加斜对角水印
*
* @param waterMarkContent 水印文字
* @param srcImgPath 源文件路径
* @param os 输出流
*/
public static void waterPressOneText(String waterMarkContent, String srcImgPath, OutputStream os) {
InputStream is = null;
try {
//1、源图片
Image srcImg = ImageIO.read(new File(srcImgPath));
// 原图宽度
int srcImgWidth = srcImg.getWidth(null);
int srcImgHeight = srcImg.getHeight(null);
BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
//2、得到画笔对象
Graphics2D g = buffImg.createGraphics();
//3、设置对线段的锯齿状边缘处理
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(
srcImg.getScaledInstance(srcImg.getWidth(null),
srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0, null);
//4、设置水印旋转
//设置旋转角度为图片斜对角的角度
Integer degree = -45;
if (null != degree) {
g.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);
}
//以图片宽度为度量,设置对应的字体大小
int fontSize;
if (srcImgWidth <= 3000) fontSize = 50;
else fontSize = (int) (srcImgWidth * 0.05);
//5、设置水印文字颜色
g.setColor(color);
//6、设置水印文字Font
Font font = new Font("宋体", Font.PLAIN, fontSize);
g.setFont(font);
//7、设置水印文字透明度
// g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5F));
//8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
Integer positionWidth = srcImgWidth / 2;
Integer positionHeight = srcImgHeight / 2;
g.drawString(waterMarkContent, positionWidth, positionHeight);//9、释放资源
g.dispose();//10、生成图片
ImageIO.write(buffImg, "JPG", os);
System.out.println("图片完成添加水印文字");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != is)
is.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
if (null != os)
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}