AddWatermarkUtil.java 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. package com.ruoyi.common.utils;
  2. import org.apache.commons.compress.utils.IOUtils;
  3. import org.apache.commons.fileupload.FileItem;
  4. import org.apache.commons.fileupload.disk.DiskFileItemFactory;
  5. import org.springframework.http.MediaType;
  6. import org.springframework.web.multipart.MultipartFile;
  7. import org.springframework.web.multipart.commons.CommonsMultipartFile;
  8. import javax.imageio.ImageIO;
  9. import java.awt.*;
  10. import java.awt.font.FontRenderContext;
  11. import java.awt.font.TextLayout;
  12. import java.awt.geom.AffineTransform;
  13. import java.awt.image.BufferedImage;
  14. import java.io.*;
  15. /**
  16. * @ProjectName: test
  17. * @Package: com.test.utils
  18. * @ClassName: MyTest
  19. * @Author: ***
  20. * @Description:
  21. * @Date: 2020/10/29 11:48
  22. * @Version: 1.0
  23. */
  24. public class AddWatermarkUtil {
  25. public static void waterPress(File srcImgFile, File outputFile,
  26. Color markContentColor, int fontSize, String waterMarkContent) {
  27. try {
  28. String[] waterMarkContents = waterMarkContent.split("\\|\\|");
  29. // 读取原图片信息
  30. Image srcImg = ImageIO.read(srcImgFile);
  31. int srcImgWidth = srcImg.getWidth(null);
  32. int srcImgHeight = srcImg.getHeight(null);
  33. // 加水印
  34. BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
  35. // 得到画笔对象
  36. Graphics2D g = bufImg.createGraphics();
  37. // 设置起点
  38. g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
  39. Font font = new Font("Default", Font.PLAIN, fontSize);
  40. // 水印透明度
  41. g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5F));
  42. // 根据图片的背景设置水印颜色
  43. g.setColor(markContentColor);
  44. // 设置水印文字字体
  45. g.setFont(font);
  46. // 数组长度
  47. int contentLength = waterMarkContents.length;
  48. // 获取水印文字中最长的
  49. int maxLength = 0;
  50. for (int i = 0; i < contentLength; i++) {
  51. int fontlen = getWatermarkLength(waterMarkContents[i], g);
  52. if (maxLength < fontlen) {
  53. maxLength = fontlen;
  54. }
  55. }
  56. for (int j = 0; j < contentLength; j++) {
  57. waterMarkContent = waterMarkContents[j];
  58. int tempX = 10;
  59. int tempY = fontSize;
  60. // 单字符长度
  61. int tempCharLen = 0;
  62. // 单行字符总长度临时计算
  63. int tempLineLen = 0;
  64. StringBuffer sb = new StringBuffer();
  65. for (int i = 0; i < waterMarkContent.length(); i++) {
  66. char tempChar = waterMarkContent.charAt(i);
  67. tempCharLen = getCharLen(tempChar, g);
  68. tempLineLen += tempCharLen;
  69. if (tempLineLen >= srcImgWidth) {
  70. // 长度已经满一行,进行文字叠加
  71. g.drawString(sb.toString(), tempX, tempY);
  72. // 清空内容,重新追加
  73. sb.delete(0, sb.length());
  74. tempLineLen = 0;
  75. }
  76. // 追加字符
  77. sb.append(tempChar);
  78. }
  79. // 通过设置后两个输入参数给水印定位
  80. g.drawString(sb.toString(), 20, srcImgHeight - (contentLength - j - 1) * tempY - 50);
  81. }
  82. g.dispose();
  83. // 输出图片
  84. // 释放资源
  85. g.dispose();
  86. ImageIO.write(bufImg, "PNG", outputFile);
  87. } catch (Exception e) {
  88. e.printStackTrace();
  89. }
  90. }
  91. public static int getCharLen(char c, Graphics2D g) {
  92. return g.getFontMetrics(g.getFont()).charWidth(c);
  93. }
  94. /**
  95. * 获取水印文字总长度
  96. *
  97. * @paramwaterMarkContent水印的文字
  98. * @paramg
  99. * @return水印文字总长度
  100. */
  101. public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
  102. return g.getFontMetrics(g.getFont()).charsWidth(
  103. waterMarkContent.toCharArray(), 0, waterMarkContent.length());
  104. }
  105. /**
  106. * 添加倾斜水印
  107. *
  108. * @param inputFile 图片
  109. * @param outputFile
  110. * @param text
  111. * @throws IOException
  112. */
  113. public static void addWaterMark(File inputFile, File outputFile, String text) throws IOException {
  114. Image image = ImageIO.read(inputFile);
  115. int imgWidth = image.getWidth(null);// 获取图片的宽
  116. int imgHeight = image.getHeight(null);// 获取图片的高
  117. int angel = 315;// 旋转角度
  118. int xpadding = 40;// 每个水印水平间隔
  119. int ypadding = 40;// 每个水印垂直间隔
  120. int fontSize = 10;
  121. BufferedImage bi = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_ARGB);
  122. Graphics2D g = bi.createGraphics();
  123. g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  124. // 绘制原图片
  125. float alpha = 1F;
  126. AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
  127. g.setComposite(ac);
  128. g.drawImage(image, 0, 0, imgWidth, imgHeight, null);
  129. g.setBackground(Color.BLACK);
  130. // 开始绘制水印
  131. // 水印字体
  132. Font font = new Font("Default", Font.BOLD, fontSize);
  133. g.setFont(font);
  134. FontRenderContext frc = g.getFontRenderContext();
  135. TextLayout tl = new TextLayout(text, font, frc);
  136. // 水印串宽度
  137. int stringWidth = g.getFontMetrics(g.getFont()).charsWidth(text.toCharArray(), 0, text.length());
  138. // 旋转水印
  139. // g.rotate(Math.toRadians(angel), (double) imgWidth / 2, (double) imgHeight / 2);
  140. // 水印透明度
  141. // g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5F));
  142. // 字体色
  143. g.setColor(Color.RED);
  144. int x = -imgHeight / 2;
  145. int y = -imgWidth / 2;
  146. // 循环绘制
  147. while (x < imgWidth + imgHeight / 2) {
  148. y = -imgWidth / 2;
  149. while (y < imgHeight + imgWidth / 2) {
  150. Shape sha = tl.getOutline(AffineTransform.getTranslateInstance(x, y));
  151. g.fill(sha);
  152. y += ypadding;
  153. }
  154. x += stringWidth + xpadding;
  155. }
  156. // 释放资源
  157. g.dispose();
  158. ImageIO.write(bi, "PNG", outputFile);
  159. }
  160. /**
  161. * MultipartFile 转 File
  162. * @param multipartFile
  163. * @return
  164. */
  165. public static File transferToFile(MultipartFile multipartFile) {
  166. //选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 。
  167. File file = null;
  168. try {
  169. String originalFilename = multipartFile.getOriginalFilename();
  170. String[] filename = originalFilename.split("\\.");
  171. file = File.createTempFile(filename[0], filename[1]);
  172. multipartFile.transferTo(file);
  173. file.deleteOnExit();
  174. } catch (IOException e) {
  175. e.printStackTrace();
  176. }
  177. return file;
  178. }
  179. /**
  180. * File 转 MultipartFile
  181. * @param file
  182. * @return
  183. */
  184. public static MultipartFile fileToTransfer(File file) {
  185. FileItem item = new DiskFileItemFactory().createItem("file"
  186. , MediaType.MULTIPART_FORM_DATA_VALUE
  187. , true
  188. , file.getName());
  189. try (InputStream input = new FileInputStream(file);
  190. OutputStream os = item.getOutputStream()) {
  191. // 流转移
  192. IOUtils.copy(input, os);
  193. } catch (Exception e) {
  194. throw new IllegalArgumentException("Invalid file: " + e, e);
  195. }
  196. return new CommonsMultipartFile(item);
  197. }
  198. }