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; } }