825 lines
31 KiB
Java
825 lines
31 KiB
Java
package aiyh.utils.fileUtil;
|
||
|
||
import aiyh.utils.zwl.common.ToolUtil;
|
||
import sun.font.FontDesignMetrics;
|
||
import weaver.conn.RecordSet;
|
||
import weaver.file.FileUpload;
|
||
import weaver.file.ImageFileManager;
|
||
import weaver.general.Util;
|
||
import weaver.system.SystemComInfo;
|
||
|
||
import javax.imageio.ImageIO;
|
||
import javax.swing.*;
|
||
import java.awt.*;
|
||
import java.awt.image.BufferedImage;
|
||
import java.io.*;
|
||
import java.net.URLDecoder;
|
||
import java.nio.file.Files;
|
||
import java.nio.file.Paths;
|
||
import java.util.UUID;
|
||
|
||
/**
|
||
* @author EBU7-dev1-ayh
|
||
* @date 2021/9/2 0002 16:59
|
||
* 水印图片封装
|
||
*/
|
||
|
||
|
||
public class WritWatermark {
|
||
|
||
private static final ToolUtil toolUtil = new ToolUtil();
|
||
|
||
/**
|
||
* 根据系统中物理文件的id添加水印
|
||
*
|
||
* @param imageId 物理文件id
|
||
* @param pressText 水印文字
|
||
* @param color 水印文字颜色
|
||
* @param fontName 水印文字字体 PLAIN(普通) BOLD(粗体) ITALIC(斜体)
|
||
* @param fontStyle 水印文字样式
|
||
* @param fontSize 水印文字大小
|
||
* @param watermarkPoint 水印位置对象
|
||
* @param degree 旋转角度
|
||
* @param alpha 透明度 0-1
|
||
* @param lineSpacing 行间距(倍数)
|
||
* @return 带水印的物理图片的ID
|
||
* @throws IOException io异常
|
||
*/
|
||
public static int addTextWatermarkById(int imageId, String pressText, Color color, String fontName, int fontStyle
|
||
, int fontSize, WatermarkPoint watermarkPoint, double degree, float alpha, double lineSpacing) throws IOException {
|
||
ImageFileManager imageFileManager = new ImageFileManager();
|
||
// 通过文件id获取输入流
|
||
InputStream inputStreamById = ImageFileManager.getInputStreamById(imageId);
|
||
if (inputStreamById == null) {
|
||
throw new RuntimeException("Failed to obtain the image to which a watermark is to be added. " +
|
||
"Check whether the file exists in the system and ensure that the file is in the image format.");
|
||
}
|
||
// 将输入流读取为图片
|
||
Image image = ImageIO.read(inputStreamById);
|
||
int width = image.getWidth(null);
|
||
int height = image.getHeight(null);
|
||
// 创建bufferedImage
|
||
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||
Graphics2D graphics = bufferedImage.createGraphics();
|
||
// 设置对线段的锯齿状边缘处理
|
||
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||
graphics.drawImage(image, 0, 0, width, height, null);
|
||
String[] pressTexts = pressText.split("\n");
|
||
String maxStr = "";
|
||
int max = 0;
|
||
// 求出最大长度值
|
||
for (String press : pressTexts) {
|
||
if (press.length() > max) {
|
||
max = press.length();
|
||
maxStr = press;
|
||
}
|
||
}
|
||
String message = maxStr;
|
||
Font defaultFont = new Font(fontName,fontStyle,fontSize);
|
||
int wordWidth = getWordWidth(defaultFont, message);
|
||
// 对字体进行限制
|
||
if (wordWidth >= Math.min(width, height)) {
|
||
fontSize = (int) (Math.min(width, height) / (pressText.length() + 6));
|
||
}
|
||
toolUtil.writeDebuggerLog(String.format(
|
||
"图片宽度{%s},图片高度{%s},文字宽度{%s},文字{%s},字体大小{%s},字体数量{%s}"
|
||
,width,height,wordWidth,message,fontSize,message.length()));
|
||
double lineHeight = fontSize * lineSpacing;
|
||
Font font = new Font(fontName, fontStyle, fontSize);
|
||
graphics.setColor(color);
|
||
graphics.setFont(font);
|
||
// 设置旋转角度
|
||
graphics.rotate(Math.toRadians(degree), (double) width / 2, (double) height / 2);
|
||
// 设置透明度
|
||
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
|
||
|
||
int X;
|
||
int Y;
|
||
int fontWidth = graphics.getFontMetrics(graphics.getFont()).charsWidth(maxStr.toCharArray(), 0, max);
|
||
int fontsHeight = (int) Math.round(lineHeight) * pressTexts.length;
|
||
if (watermarkPoint.getLocation() == null) {
|
||
X = watermarkPoint.getX();
|
||
Y = watermarkPoint.getY();
|
||
} else {
|
||
// 水印放在中间
|
||
if (watermarkPoint.getLocation().equals(WatermarkPointEnum.CENTER)) {
|
||
X = (width / 2) - (fontWidth / 2);
|
||
Y = (height / 2) - (fontsHeight / 2);
|
||
} else if (watermarkPoint.getLocation().equals(WatermarkPointEnum.LEFT_TOP)) {
|
||
// 水印放在左上
|
||
X = 10;
|
||
Y = 10;
|
||
} else if (watermarkPoint.getLocation().equals(WatermarkPointEnum.LEFT_BOTTOM)) {
|
||
// 水印放在左下
|
||
X = 10;
|
||
Y = height - fontsHeight - 10;
|
||
} else if (watermarkPoint.getLocation().equals(WatermarkPointEnum.RIGHT_TOP)) {
|
||
// 水印放在右上
|
||
X = width - fontWidth - 10;
|
||
Y = 10;
|
||
} else {
|
||
// 水印放在右下
|
||
X = width - fontWidth - 10;
|
||
Y = height - fontsHeight - 10;
|
||
}
|
||
}
|
||
|
||
for (int i = 0; i < pressTexts.length; i++) {
|
||
// 防止重叠,需要对Y进行特殊处理
|
||
graphics.drawString(pressTexts[i], X, Y + ((int) Math.round(lineHeight) * (i + 1)));
|
||
}
|
||
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
|
||
graphics.dispose();
|
||
// 获取图片后缀
|
||
String query = "select imagefilename from imagefile where imagefileid = ?";
|
||
RecordSet rs = new RecordSet();
|
||
rs.executeQuery(query, imageId);
|
||
String suffix = "jpg";
|
||
String imageFileName = "";
|
||
if (rs.next()) {
|
||
imageFileName = Util.null2String(rs.getString(1));
|
||
suffix = imageFileName.substring(imageFileName.lastIndexOf(".") + 1);
|
||
}
|
||
String createDir = FileUpload.getCreateDir(new SystemComInfo().getFilesystem()) + "tempfile" + File.separator;
|
||
// 防止高并发下文件名重复导致文件覆盖的问题
|
||
String tempPath = createDir + imageFileName + System.currentTimeMillis() + UUID.randomUUID() + "." + suffix;
|
||
File file = new File(tempPath);
|
||
if (!file.getParentFile().exists()) {
|
||
file.getParentFile().mkdirs();
|
||
}
|
||
if (!file.exists()) {
|
||
file.createNewFile();
|
||
}
|
||
// 输出到临时目录
|
||
FileOutputStream outputStreamTem = new FileOutputStream(URLDecoder.decode(tempPath, "utf-8"));
|
||
ImageIO.write(bufferedImage, suffix, outputStreamTem);
|
||
outputStreamTem.close();
|
||
// 保存生成的水印图片到压缩包
|
||
int i = imageFileManager.saveImageFileByInputStream(new FileInputStream(tempPath), imageFileName);
|
||
// 建议虚拟机进行一次垃圾回收,防止临时文件被其他文件流保存而无法删除临时文件
|
||
System.gc();
|
||
// 删除临时文件, 防止文件删除失败,设置一个自旋操作,加大文件删除的几率
|
||
boolean deleteFlag = true;
|
||
int n = 0;
|
||
while (deleteFlag) {
|
||
try {
|
||
n++;
|
||
Files.delete(Paths.get(tempPath));
|
||
deleteFlag = false;
|
||
} catch (Exception e) {
|
||
// 设置线程沉睡500毫秒,等待jvm进行垃圾回收,将持有临时文件的流对象回收,确保临时文件能删除
|
||
try {
|
||
Thread.sleep(500);
|
||
} catch (InterruptedException interruptedException) {
|
||
return i;
|
||
}
|
||
if (n > 5) {
|
||
deleteFlag = false;
|
||
}
|
||
}
|
||
}
|
||
return i;
|
||
}
|
||
|
||
|
||
/**
|
||
* 通过物理问文件id添加图片水印
|
||
*
|
||
* @param imageId 物理文件id
|
||
* @param picId 水印图片物理文件id
|
||
* @param watermarkPoint 水印位置对象
|
||
* @param degree 旋转角度
|
||
* @param alpha 透明度 0-1
|
||
* @return 带水印的物理图片的ID
|
||
* @throws IOException io异常
|
||
*/
|
||
public static int addPicWatermarkById(int imageId, int picId
|
||
, WatermarkPoint watermarkPoint, double degree, float alpha) throws IOException {
|
||
ImageFileManager imageFileManager = new ImageFileManager();
|
||
// 通过文件id获取输入流
|
||
InputStream inputStreamById = ImageFileManager.getInputStreamById(imageId);
|
||
if (inputStreamById == null) {
|
||
throw new RuntimeException("Failed to obtain the image to which a watermark is to be added. " +
|
||
"Check whether the file exists in the system and ensure that the file is in the image format.");
|
||
}
|
||
// 将输入流读取为图片
|
||
Image image = ImageIO.read(inputStreamById);
|
||
int width = image.getWidth(null);
|
||
int height = image.getHeight(null);
|
||
// 创建bufferedImage
|
||
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||
Graphics2D graphics = bufferedImage.createGraphics();
|
||
// 设置对线段的锯齿状边缘处理
|
||
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||
graphics.drawImage(image, 0, 0, width, height, null);
|
||
// 设置旋转角度
|
||
graphics.rotate(Math.toRadians(degree), (double) width / 2, (double) height / 2);
|
||
// 设置透明度
|
||
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
|
||
// 获取水印图片
|
||
InputStream inputStreamImgIcon = ImageFileManager.getInputStreamById(picId);
|
||
if (inputStreamImgIcon == null) {
|
||
throw new RuntimeException("The obtained watermark logo image is empty");
|
||
}
|
||
Image logoImg = ImageIO.read(inputStreamImgIcon);
|
||
int logoWidth = logoImg.getWidth(null);
|
||
int logoHeight = logoImg.getHeight(null);
|
||
int X;
|
||
int Y;
|
||
if (watermarkPoint.getLocation() == null) {
|
||
X = watermarkPoint.getX();
|
||
Y = watermarkPoint.getY();
|
||
} else {
|
||
// 水印放在中间
|
||
if (watermarkPoint.getLocation().equals(WatermarkPointEnum.CENTER)) {
|
||
X = (width / 2) - (logoWidth / 2);
|
||
Y = (height / 2) - (logoHeight / 2);
|
||
} else if (watermarkPoint.getLocation().equals(WatermarkPointEnum.LEFT_TOP)) {
|
||
// 水印放在左上
|
||
X = 10;
|
||
Y = 10;
|
||
} else if (watermarkPoint.getLocation().equals(WatermarkPointEnum.LEFT_BOTTOM)) {
|
||
// 水印放在左下
|
||
X = 10;
|
||
Y = height - logoHeight - 10;
|
||
} else if (watermarkPoint.getLocation().equals(WatermarkPointEnum.RIGHT_TOP)) {
|
||
// 水印放在右上
|
||
X = width - logoWidth - 10;
|
||
Y = 10;
|
||
} else {
|
||
// 水印放在右下
|
||
X = width - logoWidth - 10;
|
||
Y = height - logoHeight - 10;
|
||
}
|
||
}
|
||
graphics.drawImage(logoImg, X, Y, null);
|
||
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
|
||
graphics.dispose();
|
||
// 获取图片后缀
|
||
String query = "select imagefilename from imagefile where imagefileid = ?";
|
||
RecordSet rs = new RecordSet();
|
||
rs.executeQuery(query, imageId);
|
||
String suffix = "jpg";
|
||
String imageFileName = "";
|
||
if (rs.next()) {
|
||
imageFileName = Util.null2String(rs.getString(1));
|
||
suffix = imageFileName.substring(imageFileName.lastIndexOf(".") + 1);
|
||
}
|
||
String createDir = FileUpload.getCreateDir(new SystemComInfo().getFilesystem()) + "tempfile" + File.separator;
|
||
// 防止高并发下文件名重复导致文件覆盖的问题
|
||
String tempPath = createDir + imageFileName + System.currentTimeMillis() + UUID.randomUUID() + "." + suffix;
|
||
File file = new File(tempPath);
|
||
if (!file.getParentFile().exists()) {
|
||
file.getParentFile().mkdirs();
|
||
}
|
||
if (!file.exists()) {
|
||
file.createNewFile();
|
||
}
|
||
// 输出到临时目录
|
||
FileOutputStream outputStreamTem = new FileOutputStream(URLDecoder.decode(tempPath, "utf-8"));
|
||
ImageIO.write(bufferedImage, suffix, outputStreamTem);
|
||
outputStreamTem.close();
|
||
// 保存生成的水印图片到压缩包
|
||
int i = imageFileManager.saveImageFileByInputStream(new FileInputStream(tempPath), imageFileName);
|
||
// 建议虚拟机进行一次垃圾回收,防止临时文件被其他文件流保存而无法删除临时文件
|
||
System.gc();
|
||
// 删除临时文件, 防止文件删除失败,设置一个自旋操作,加大文件删除的几率
|
||
boolean deleteFlag = true;
|
||
int n = 0;
|
||
while (deleteFlag) {
|
||
try {
|
||
n++;
|
||
Files.delete(Paths.get(tempPath));
|
||
deleteFlag = false;
|
||
} catch (Exception e) {
|
||
// 设置线程沉睡500毫秒,等待jvm进行垃圾回收,将持有临时文件的流对象回收,确保临时文件能删除
|
||
try {
|
||
Thread.sleep(500);
|
||
} catch (InterruptedException interruptedException) {
|
||
return i;
|
||
}
|
||
if (n > 5) {
|
||
deleteFlag = false;
|
||
}
|
||
}
|
||
}
|
||
return i;
|
||
}
|
||
|
||
|
||
/**
|
||
* 通过物理问文件id添加图片水印
|
||
*
|
||
* @param imageId 水印图片物理文件id
|
||
* @param logoInput 水印图片的输入流
|
||
* @param watermarkPoint 水印位置对象
|
||
* @param degree 旋转角度
|
||
* @param alpha 透明度 0-1
|
||
* @return 带水印的物理图片的ID
|
||
* @throws IOException io异常
|
||
*/
|
||
public static int addPicWatermarkById(int imageId, InputStream logoInput
|
||
, WatermarkPoint watermarkPoint, double degree, float alpha) throws IOException {
|
||
ImageFileManager imageFileManager = new ImageFileManager();
|
||
// 通过文件id获取输入流
|
||
InputStream inputStreamById = ImageFileManager.getInputStreamById(imageId);
|
||
if (inputStreamById == null) {
|
||
throw new RuntimeException("Failed to obtain the image to which a watermark is to be added. " +
|
||
"Check whether the file exists in the system and ensure that the file is in the image format.");
|
||
}
|
||
// 将输入流读取为图片
|
||
Image image = ImageIO.read(inputStreamById);
|
||
int width = image.getWidth(null);
|
||
int height = image.getHeight(null);
|
||
// 创建bufferedImage
|
||
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||
Graphics2D graphics = bufferedImage.createGraphics();
|
||
// 设置对线段的锯齿状边缘处理
|
||
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||
graphics.drawImage(image, 0, 0, width, height, null);
|
||
// 设置旋转角度
|
||
graphics.rotate(Math.toRadians(degree), (double) width / 2, (double) height / 2);
|
||
// 设置透明度
|
||
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
|
||
if (logoInput == null) {
|
||
throw new RuntimeException("The obtained watermark logo image is empty");
|
||
}
|
||
// 获取水印图片
|
||
ImageIcon logoImgIcon = new ImageIcon(ImageIO.read(logoInput));
|
||
Image logoImg = logoImgIcon.getImage();
|
||
int logoWidth = logoImg.getWidth(null);
|
||
int logoHeight = logoImg.getHeight(null);
|
||
int X;
|
||
int Y;
|
||
if (watermarkPoint.getLocation() == null) {
|
||
X = watermarkPoint.getX();
|
||
Y = watermarkPoint.getY();
|
||
} else {
|
||
// 水印放在中间
|
||
if (watermarkPoint.getLocation().equals(WatermarkPointEnum.CENTER)) {
|
||
X = (width / 2) - (logoWidth / 2);
|
||
Y = (height / 2) - (logoHeight / 2);
|
||
} else if (watermarkPoint.getLocation().equals(WatermarkPointEnum.LEFT_TOP)) {
|
||
// 水印放在左上
|
||
X = 10;
|
||
Y = 10;
|
||
} else if (watermarkPoint.getLocation().equals(WatermarkPointEnum.LEFT_BOTTOM)) {
|
||
// 水印放在左下
|
||
X = 10;
|
||
Y = height - logoHeight - 10;
|
||
} else if (watermarkPoint.getLocation().equals(WatermarkPointEnum.RIGHT_TOP)) {
|
||
// 水印放在右上
|
||
X = width - logoWidth - 10;
|
||
Y = 10;
|
||
} else {
|
||
// 水印放在右下
|
||
X = width - logoWidth - 10;
|
||
Y = height - logoHeight - 10;
|
||
}
|
||
}
|
||
graphics.drawImage(logoImg, X, Y, null);
|
||
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
|
||
graphics.dispose();
|
||
// 获取图片后缀
|
||
String query = "select imagefilename from imagefile where imagefileid = ?";
|
||
RecordSet rs = new RecordSet();
|
||
rs.executeQuery(query, imageId);
|
||
String suffix = "jpg";
|
||
String imageFileName = "";
|
||
if (rs.next()) {
|
||
imageFileName = Util.null2String(rs.getString(1));
|
||
suffix = imageFileName.substring(imageFileName.lastIndexOf(".") + 1);
|
||
}
|
||
String createDir = FileUpload.getCreateDir(new SystemComInfo().getFilesystem()) + "tempfile" + File.separator;
|
||
// 防止高并发下文件名重复导致文件覆盖的问题
|
||
String tempPath = createDir + imageFileName + System.currentTimeMillis() + UUID.randomUUID() + "." + suffix;
|
||
File file = new File(tempPath);
|
||
if (!file.getParentFile().exists()) {
|
||
file.getParentFile().mkdirs();
|
||
}
|
||
if (!file.exists()) {
|
||
file.createNewFile();
|
||
}
|
||
// 输出到临时目录
|
||
FileOutputStream outputStreamTem = new FileOutputStream(URLDecoder.decode(tempPath, "utf-8"));
|
||
ImageIO.write(bufferedImage, suffix, outputStreamTem);
|
||
outputStreamTem.close();
|
||
// 保存生成的水印图片到压缩包
|
||
int i = imageFileManager.saveImageFileByInputStream(new FileInputStream(tempPath), imageFileName);
|
||
// 建议虚拟机进行一次垃圾回收,防止临时文件被其他文件流保存而无法删除临时文件
|
||
System.gc();
|
||
// 删除临时文件, 防止文件删除失败,设置一个自旋操作,加大文件删除的几率
|
||
boolean deleteFlag = true;
|
||
int n = 0;
|
||
while (deleteFlag) {
|
||
try {
|
||
n++;
|
||
Files.delete(Paths.get(tempPath));
|
||
deleteFlag = false;
|
||
} catch (Exception e) {
|
||
// 设置线程沉睡500毫秒,等待jvm进行垃圾回收,将持有临时文件的流对象回收,确保临时文件能删除
|
||
try {
|
||
Thread.sleep(500);
|
||
} catch (InterruptedException interruptedException) {
|
||
return i;
|
||
}
|
||
if (n > 5) {
|
||
deleteFlag = false;
|
||
}
|
||
}
|
||
}
|
||
return i;
|
||
}
|
||
|
||
/**
|
||
* @param imageId 物理图片id
|
||
* @param pressText 水印文字
|
||
* @param color 水印文字颜色
|
||
* @param fontName 水印字体名字
|
||
* @param fontStyle 水印字体样式
|
||
* @param fontSize 水印字体大小
|
||
* @param degree 水印旋转角度
|
||
* @param alpha 水印透明度
|
||
* @param lineSpacing 水印文字行间距(倍数)
|
||
* @param moveX 水印X轴偏移量
|
||
* @param moveY 水印Y轴偏移量
|
||
* @param randomX 水印X轴随机偏移量
|
||
* @return 带水印的物理图片id
|
||
* @throws IOException io异常
|
||
*/
|
||
public static int addTextTileWatermarkById(int imageId, String pressText, Color color, String fontName, int fontStyle
|
||
, int fontSize, double degree, float alpha, double lineSpacing, int moveX, int moveY, int randomX) throws IOException {
|
||
ImageFileManager imageFileManager = new ImageFileManager();
|
||
// 通过文件id获取输入流
|
||
InputStream inputStreamById = ImageFileManager.getInputStreamById(imageId);
|
||
if (inputStreamById == null) {
|
||
throw new RuntimeException("Failed to obtain the image to which a watermark is to be added. " +
|
||
"Check whether the file exists in the system and ensure that the file is in the image format.");
|
||
}
|
||
// 将输入流读取为图片
|
||
Image image = ImageIO.read(inputStreamById);
|
||
int width = image.getWidth(null);
|
||
int height = image.getHeight(null);
|
||
double lineHeight = fontSize * lineSpacing;
|
||
// 创建bufferedImage
|
||
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||
Graphics2D graphics = bufferedImage.createGraphics();
|
||
// 设置对线段的锯齿状边缘处理
|
||
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||
graphics.drawImage(image, 0, 0, width, height, null);
|
||
Font font = new Font(fontName, fontStyle, fontSize);
|
||
graphics.setColor(color);
|
||
graphics.setFont(font);
|
||
// 设置旋转角度
|
||
graphics.rotate(Math.toRadians(degree), (double) width / 2, (double) height / 2);
|
||
// 设置透明度
|
||
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
|
||
String[] pressTexts = pressText.split("\n");
|
||
String maxStr = "";
|
||
int max = 0;
|
||
// 求出最大长度值
|
||
for (String press : pressTexts) {
|
||
if (press.length() > max) {
|
||
max = press.length();
|
||
maxStr = press;
|
||
}
|
||
}
|
||
int X;
|
||
int Y;
|
||
int fontWidth = graphics.getFontMetrics(graphics.getFont()).charsWidth(maxStr.toCharArray(), 0, max);
|
||
int fontsHeight = (int) Math.round(lineHeight) * pressTexts.length;
|
||
int mustX = fontWidth;
|
||
int mustY = fontsHeight;
|
||
int start = -(width + height);
|
||
int end = width + height;
|
||
X = start;
|
||
Y = start;
|
||
int random = 0;
|
||
|
||
// 循环Y,每次偏移防止重叠的最小偏移量加上自定义的偏移量
|
||
for (; Y <= end; Y = Y + moveY + mustY) {
|
||
// 循环X,每次偏移防止重叠的最小偏移量加上自定义偏移量
|
||
for (; X <= end; X = X + moveX + mustX) {
|
||
for (int i = 0; i < pressTexts.length; i++) {
|
||
// 防止重叠对Y做文字偏移
|
||
graphics.drawString(pressTexts[i], X + random, Y + (int) Math.ceil(lineHeight) * (i + 1));
|
||
}
|
||
|
||
}
|
||
X = start;
|
||
if (random == 0) {
|
||
random = -randomX;
|
||
} else {
|
||
random = 0;
|
||
}
|
||
}
|
||
|
||
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
|
||
graphics.dispose();
|
||
// 获取图片后缀
|
||
String query = "select imagefilename from imagefile where imagefileid = ?";
|
||
RecordSet rs = new RecordSet();
|
||
rs.executeQuery(query, imageId);
|
||
String suffix = "jpg";
|
||
String imageFileName = "";
|
||
if (rs.next()) {
|
||
imageFileName = Util.null2String(rs.getString(1));
|
||
suffix = imageFileName.substring(imageFileName.lastIndexOf(".") + 1);
|
||
}
|
||
String createDir = FileUpload.getCreateDir(new SystemComInfo().getFilesystem()) + "tempfile" + File.separator;
|
||
// 防止高并发下文件名重复导致文件覆盖的问题
|
||
String tempPath = createDir + imageFileName + System.currentTimeMillis() + UUID.randomUUID() + "." + suffix;
|
||
File file = new File(tempPath);
|
||
if (!file.getParentFile().exists()) {
|
||
file.getParentFile().mkdirs();
|
||
}
|
||
if (!file.exists()) {
|
||
file.createNewFile();
|
||
}
|
||
// 输出到临时目录
|
||
FileOutputStream outputStreamTem = new FileOutputStream(URLDecoder.decode(tempPath, "utf-8"));
|
||
ImageIO.write(bufferedImage, suffix, outputStreamTem);
|
||
outputStreamTem.close();
|
||
// 保存生成的水印图片到压缩包
|
||
int i = imageFileManager.saveImageFileByInputStream(new FileInputStream(tempPath), imageFileName);
|
||
// 建议虚拟机进行一次垃圾回收,防止临时文件被其他文件流保存而无法删除临时文件
|
||
System.gc();
|
||
// 删除临时文件, 防止文件删除失败,设置一个自旋操作,加大文件删除的几率
|
||
boolean deleteFlag = true;
|
||
int n = 0;
|
||
while (deleteFlag) {
|
||
try {
|
||
n++;
|
||
Files.delete(Paths.get(tempPath));
|
||
deleteFlag = false;
|
||
} catch (Exception e) {
|
||
// 设置线程沉睡500毫秒,等待jvm进行垃圾回收,将持有临时文件的流对象回收,确保临时文件能删除
|
||
try {
|
||
Thread.sleep(500);
|
||
} catch (InterruptedException interruptedException) {
|
||
return i;
|
||
}
|
||
if (n > 5) {
|
||
deleteFlag = false;
|
||
}
|
||
}
|
||
}
|
||
return i;
|
||
}
|
||
|
||
/**
|
||
* @param imageId 物理图片id
|
||
* @param picId 水印物理文件id
|
||
* @param degree 水印旋转角度
|
||
* @param alpha 水印透明度
|
||
* @param moveX 水印X轴偏移量
|
||
* @param moveY 水印Y轴偏移量
|
||
* @param randomX 水印X轴随机偏移量
|
||
* @return 带水印的物理图片id
|
||
* @throws IOException io异常
|
||
*/
|
||
public static int addPicTileWatermarkById(int imageId, int picId
|
||
, double degree, float alpha, int moveX, int moveY, int randomX) throws IOException {
|
||
ImageFileManager imageFileManager = new ImageFileManager();
|
||
// 通过文件id获取输入流
|
||
InputStream inputStreamById = ImageFileManager.getInputStreamById(imageId);
|
||
if (inputStreamById == null) {
|
||
throw new RuntimeException("Failed to obtain the image to which a watermark is to be added. " +
|
||
"Check whether the file exists in the system and ensure that the file is in the image format.");
|
||
}
|
||
// 将输入流读取为图片
|
||
Image image = ImageIO.read(inputStreamById);
|
||
int width = image.getWidth(null);
|
||
int height = image.getHeight(null);
|
||
// 创建bufferedImage
|
||
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||
Graphics2D graphics = bufferedImage.createGraphics();
|
||
// 设置对线段的锯齿状边缘处理
|
||
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||
graphics.drawImage(image, 0, 0, width, height, null);
|
||
// 设置旋转角度
|
||
graphics.rotate(Math.toRadians(degree), (double) width / 2, (double) height / 2);
|
||
// 设置透明度
|
||
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
|
||
// 获取水印图片
|
||
InputStream inputStreamImgIcon = ImageFileManager.getInputStreamById(picId);
|
||
if (inputStreamImgIcon == null) {
|
||
throw new RuntimeException("The obtained watermark logo image is empty");
|
||
}
|
||
ImageIcon logoImgIcon = new ImageIcon(ImageIO.read(inputStreamImgIcon));
|
||
Image logoImg = logoImgIcon.getImage();
|
||
int logoWidth = logoImg.getWidth(null);
|
||
int logoHeight = logoImg.getHeight(null);
|
||
int X;
|
||
int Y;
|
||
int mustX = logoWidth;
|
||
int mustY = logoHeight;
|
||
int start = -(width + height);
|
||
int end = width + height;
|
||
X = start;
|
||
Y = start;
|
||
int random = 0;
|
||
|
||
// 循环Y,每次偏移防止重叠的最小偏移量加上自定义的偏移量
|
||
for (; Y <= end; Y = Y + moveY + mustY) {
|
||
// 循环X,每次偏移防止重叠的最小偏移量加上自定义偏移量
|
||
for (; X <= end; X = X + moveX + mustX) {
|
||
graphics.drawImage(logoImg, X + random, Y, null);
|
||
}
|
||
X = start;
|
||
if (random == 0) {
|
||
random = -randomX;
|
||
} else {
|
||
random = 0;
|
||
}
|
||
}
|
||
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
|
||
graphics.dispose();
|
||
// 获取图片后缀
|
||
String query = "select imagefilename from imagefile where imagefileid = ?";
|
||
RecordSet rs = new RecordSet();
|
||
rs.executeQuery(query, imageId);
|
||
String suffix = "jpg";
|
||
String imageFileName = "";
|
||
if (rs.next()) {
|
||
imageFileName = Util.null2String(rs.getString(1));
|
||
suffix = imageFileName.substring(imageFileName.lastIndexOf(".") + 1);
|
||
}
|
||
String createDir = FileUpload.getCreateDir(new SystemComInfo().getFilesystem()) + "tempfile" + File.separator;
|
||
// 防止高并发下文件名重复导致文件覆盖的问题
|
||
String tempPath = createDir + imageFileName + System.currentTimeMillis() + UUID.randomUUID() + "." + suffix;
|
||
File file = new File(tempPath);
|
||
if (!file.getParentFile().exists()) {
|
||
file.getParentFile().mkdirs();
|
||
}
|
||
if (!file.exists()) {
|
||
file.createNewFile();
|
||
}
|
||
// 输出到临时目录
|
||
FileOutputStream outputStreamTem = new FileOutputStream(URLDecoder.decode(tempPath, "utf-8"));
|
||
ImageIO.write(bufferedImage, suffix, outputStreamTem);
|
||
outputStreamTem.close();
|
||
// 保存生成的水印图片到压缩包
|
||
int i = imageFileManager.saveImageFileByInputStream(new FileInputStream(tempPath), imageFileName);
|
||
// 建议虚拟机进行一次垃圾回收,防止临时文件被其他文件流保存而无法删除临时文件
|
||
System.gc();
|
||
// 删除临时文件, 防止文件删除失败,设置一个自旋操作,加大文件删除的几率
|
||
boolean deleteFlag = true;
|
||
int n = 0;
|
||
while (deleteFlag) {
|
||
try {
|
||
n++;
|
||
Files.delete(Paths.get(tempPath));
|
||
deleteFlag = false;
|
||
} catch (Exception e) {
|
||
// 设置线程沉睡500毫秒,等待jvm进行垃圾回收,将持有临时文件的流对象回收,确保临时文件能删除
|
||
try {
|
||
Thread.sleep(500);
|
||
} catch (InterruptedException interruptedException) {
|
||
return i;
|
||
}
|
||
if (n > 5) {
|
||
deleteFlag = false;
|
||
}
|
||
}
|
||
}
|
||
return i;
|
||
}
|
||
|
||
|
||
/**
|
||
* @param imageId 物理图片id
|
||
* @param logoInput 水印图片输入流
|
||
* @param degree 水印旋转角度
|
||
* @param alpha 水印透明度
|
||
* @param moveX 水印X轴偏移位置
|
||
* @param moveY 水印Y轴偏移位置
|
||
* @param randomX 水印X轴随机偏移量
|
||
* @return 带水印的物理图片id
|
||
* @throws IOException io异常
|
||
*/
|
||
public static int addPicTileWatermarkById(int imageId, InputStream logoInput
|
||
, double degree, float alpha, int moveX, int moveY, int randomX) throws IOException {
|
||
ImageFileManager imageFileManager = new ImageFileManager();
|
||
// 通过文件id获取输入流
|
||
InputStream inputStreamById = ImageFileManager.getInputStreamById(imageId);
|
||
if (inputStreamById == null) {
|
||
throw new RuntimeException("Failed to obtain the image to which a watermark is to be added. " +
|
||
"Check whether the file exists in the system and ensure that the file is in the image format.");
|
||
}
|
||
// 将输入流读取为图片
|
||
Image image = ImageIO.read(inputStreamById);
|
||
int width = image.getWidth(null);
|
||
int height = image.getHeight(null);
|
||
// 创建bufferedImage
|
||
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||
Graphics2D graphics = bufferedImage.createGraphics();
|
||
// 设置对线段的锯齿状边缘处理
|
||
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||
graphics.drawImage(image, 0, 0, width, height, null);
|
||
// 设置旋转角度
|
||
graphics.rotate(Math.toRadians(degree), (double) width / 2, (double) height / 2);
|
||
// 设置透明度
|
||
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
|
||
if (logoInput == null) {
|
||
throw new RuntimeException("The obtained watermark logo image is empty");
|
||
}
|
||
// 获取水印图片
|
||
ImageIcon logoImgIcon = new ImageIcon(ImageIO.read(logoInput));
|
||
Image logoImg = logoImgIcon.getImage();
|
||
int logoWidth = logoImg.getWidth(null);
|
||
int logoHeight = logoImg.getHeight(null);
|
||
int X;
|
||
int Y;
|
||
int mustX = logoWidth;
|
||
int mustY = logoHeight;
|
||
int start = -(width + height);
|
||
int end = width + height;
|
||
X = start;
|
||
Y = start;
|
||
int random = 0;
|
||
|
||
// 循环Y,每次偏移防止重叠的最小偏移量加上自定义的偏移量
|
||
for (; Y <= end; Y = Y + moveY + mustY) {
|
||
// 循环X,每次偏移防止重叠的最小偏移量加上自定义偏移量
|
||
for (; X <= end; X = X + moveX + mustX) {
|
||
graphics.drawImage(logoImg, X + random, Y, null);
|
||
}
|
||
X = start;
|
||
if (random == 0) {
|
||
random = -randomX;
|
||
} else {
|
||
random = 0;
|
||
}
|
||
}
|
||
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
|
||
graphics.dispose();
|
||
// 获取图片后缀
|
||
String query = "select imagefilename from imagefile where imagefileid = ?";
|
||
RecordSet rs = new RecordSet();
|
||
rs.executeQuery(query, imageId);
|
||
String suffix = "jpg";
|
||
String imageFileName = "";
|
||
if (rs.next()) {
|
||
imageFileName = Util.null2String(rs.getString(1));
|
||
suffix = imageFileName.substring(imageFileName.lastIndexOf(".") + 1);
|
||
}
|
||
String createDir = FileUpload.getCreateDir(new SystemComInfo().getFilesystem()) + "tempfile" + File.separator;
|
||
// 防止高并发下文件名重复导致文件覆盖的问题
|
||
String tempPath = createDir + imageFileName + System.currentTimeMillis() + UUID.randomUUID() + "." + suffix;
|
||
File file = new File(tempPath);
|
||
if (!file.getParentFile().exists()) {
|
||
file.getParentFile().mkdirs();
|
||
}
|
||
if (!file.exists()) {
|
||
file.createNewFile();
|
||
}
|
||
// 输出到临时目录
|
||
FileOutputStream outputStreamTem = new FileOutputStream(URLDecoder.decode(tempPath, "utf-8"));
|
||
ImageIO.write(bufferedImage, suffix, outputStreamTem);
|
||
outputStreamTem.close();
|
||
// 保存生成的水印图片到压缩包
|
||
int i = imageFileManager.saveImageFileByInputStream(new FileInputStream(tempPath), imageFileName);
|
||
// 建议虚拟机进行一次垃圾回收,防止临时文件被其他文件流保存而无法删除临时文件
|
||
System.gc();
|
||
// 删除临时文件, 防止文件删除失败,设置一个自旋操作,加大文件删除的几率
|
||
boolean deleteFlag = true;
|
||
int n = 0;
|
||
while (deleteFlag) {
|
||
try {
|
||
n++;
|
||
Files.delete(Paths.get(tempPath));
|
||
deleteFlag = false;
|
||
} catch (Exception e) {
|
||
// 设置线程沉睡500毫秒,等待jvm进行垃圾回收,将持有临时文件的流对象回收,确保临时文件能删除
|
||
try {
|
||
Thread.sleep(500);
|
||
} catch (InterruptedException interruptedException) {
|
||
return i;
|
||
}
|
||
if (n > 5) {
|
||
deleteFlag = false;
|
||
}
|
||
}
|
||
}
|
||
return i;
|
||
}
|
||
|
||
public static int getWordWidth(Font font, String content) {
|
||
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
|
||
int width = 0;
|
||
for (int i = 0; i < content.length(); i++) {
|
||
width += metrics.charWidth(content.charAt(i));
|
||
}
|
||
return width;
|
||
}
|
||
|
||
|
||
}
|