|
@@ -0,0 +1,219 @@
|
|
|
+package com.ruoyi.common.utils;
|
|
|
+
|
|
|
+import org.apache.commons.compress.utils.IOUtils;
|
|
|
+import org.apache.commons.fileupload.FileItem;
|
|
|
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
|
|
+import org.springframework.http.MediaType;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
|
|
|
+
|
|
|
+import javax.imageio.ImageIO;
|
|
|
+import java.awt.*;
|
|
|
+import java.awt.font.FontRenderContext;
|
|
|
+import java.awt.font.TextLayout;
|
|
|
+import java.awt.geom.AffineTransform;
|
|
|
+import java.awt.image.BufferedImage;
|
|
|
+import java.io.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @ProjectName: test
|
|
|
+ * @Package: com.test.utils
|
|
|
+ * @ClassName: MyTest
|
|
|
+ * @Author: ***
|
|
|
+ * @Description:
|
|
|
+ * @Date: 2020/10/29 11:48
|
|
|
+ * @Version: 1.0
|
|
|
+ */
|
|
|
+public class AddWatermarkUtil {
|
|
|
+ public static void waterPress(File srcImgFile, File outputFile,
|
|
|
+ Color markContentColor, int fontSize, String waterMarkContent) {
|
|
|
+ try {
|
|
|
+ String[] waterMarkContents = waterMarkContent.split("\\|\\|");
|
|
|
+ // 读取原图片信息
|
|
|
+ Image srcImg = ImageIO.read(srcImgFile);
|
|
|
+ int srcImgWidth = srcImg.getWidth(null);
|
|
|
+ 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("Default", Font.PLAIN, fontSize);
|
|
|
+ // 水印透明度
|
|
|
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5F));
|
|
|
+ // 根据图片的背景设置水印颜色
|
|
|
+ g.setColor(markContentColor);
|
|
|
+ // 设置水印文字字体
|
|
|
+ g.setFont(font);
|
|
|
+ // 数组长度
|
|
|
+ int contentLength = waterMarkContents.length;
|
|
|
+ // 获取水印文字中最长的
|
|
|
+ int maxLength = 0;
|
|
|
+ for (int i = 0; i < contentLength; i++) {
|
|
|
+ int fontlen = getWatermarkLength(waterMarkContents[i], g);
|
|
|
+ if (maxLength < fontlen) {
|
|
|
+ maxLength = fontlen;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int j = 0; j < contentLength; j++) {
|
|
|
+ waterMarkContent = waterMarkContents[j];
|
|
|
+ int tempX = 10;
|
|
|
+ int tempY = fontSize;
|
|
|
+ // 单字符长度
|
|
|
+ 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);
|
|
|
+ // 清空内容,重新追加
|
|
|
+ sb.delete(0, sb.length());
|
|
|
+ tempLineLen = 0;
|
|
|
+ }
|
|
|
+ // 追加字符
|
|
|
+ sb.append(tempChar);
|
|
|
+ }
|
|
|
+ // 通过设置后两个输入参数给水印定位
|
|
|
+ g.drawString(sb.toString(), 20, srcImgHeight - (contentLength - j - 1) * tempY - 50);
|
|
|
+ }
|
|
|
+ g.dispose();
|
|
|
+
|
|
|
+ // 输出图片
|
|
|
+ // 释放资源
|
|
|
+ g.dispose();
|
|
|
+ ImageIO.write(bufImg, "PNG", outputFile);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static int getCharLen(char c, Graphics2D g) {
|
|
|
+ return g.getFontMetrics(g.getFont()).charWidth(c);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取水印文字总长度
|
|
|
+ *
|
|
|
+ * @paramwaterMarkContent水印的文字
|
|
|
+ * @paramg
|
|
|
+ * @return水印文字总长度
|
|
|
+ */
|
|
|
+ public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
|
|
|
+ return g.getFontMetrics(g.getFont()).charsWidth(
|
|
|
+ waterMarkContent.toCharArray(), 0, waterMarkContent.length());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 添加倾斜水印
|
|
|
+ *
|
|
|
+ * @param inputFile 图片
|
|
|
+ * @param outputFile
|
|
|
+ * @param text
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ public static void addWaterMark(File inputFile, File outputFile, String text) throws IOException {
|
|
|
+ Image image = ImageIO.read(inputFile);
|
|
|
+ int imgWidth = image.getWidth(null);// 获取图片的宽
|
|
|
+ int imgHeight = image.getHeight(null);// 获取图片的高
|
|
|
+
|
|
|
+ int angel = 315;// 旋转角度
|
|
|
+ int xpadding = 40;// 每个水印水平间隔
|
|
|
+ int ypadding = 40;// 每个水印垂直间隔
|
|
|
+ int fontSize = 10;
|
|
|
+
|
|
|
+ BufferedImage bi = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_ARGB);
|
|
|
+
|
|
|
+ Graphics2D g = bi.createGraphics();
|
|
|
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
|
+
|
|
|
+ // 绘制原图片
|
|
|
+ float alpha = 1F;
|
|
|
+ AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
|
|
|
+ g.setComposite(ac);
|
|
|
+ g.drawImage(image, 0, 0, imgWidth, imgHeight, null);
|
|
|
+ g.setBackground(Color.BLACK);
|
|
|
+
|
|
|
+ // 开始绘制水印
|
|
|
+ // 水印字体
|
|
|
+ Font font = new Font("Default", Font.BOLD, fontSize);
|
|
|
+ g.setFont(font);
|
|
|
+ FontRenderContext frc = g.getFontRenderContext();
|
|
|
+ TextLayout tl = new TextLayout(text, font, frc);
|
|
|
+ // 水印串宽度
|
|
|
+ int stringWidth = g.getFontMetrics(g.getFont()).charsWidth(text.toCharArray(), 0, text.length());
|
|
|
+
|
|
|
+ // 旋转水印
|
|
|
+ // g.rotate(Math.toRadians(angel), (double) imgWidth / 2, (double) imgHeight / 2);
|
|
|
+ // 水印透明度
|
|
|
+ // g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5F));
|
|
|
+ // 字体色
|
|
|
+ g.setColor(Color.RED);
|
|
|
+
|
|
|
+ int x = -imgHeight / 2;
|
|
|
+ int y = -imgWidth / 2;
|
|
|
+
|
|
|
+ // 循环绘制
|
|
|
+ while (x < imgWidth + imgHeight / 2) {
|
|
|
+ y = -imgWidth / 2;
|
|
|
+ while (y < imgHeight + imgWidth / 2) {
|
|
|
+ Shape sha = tl.getOutline(AffineTransform.getTranslateInstance(x, y));
|
|
|
+ g.fill(sha);
|
|
|
+
|
|
|
+ y += ypadding;
|
|
|
+ }
|
|
|
+ x += stringWidth + xpadding;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 释放资源
|
|
|
+ g.dispose();
|
|
|
+ ImageIO.write(bi, "PNG", outputFile);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * MultipartFile 转 File
|
|
|
+ * @param multipartFile
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static File transferToFile(MultipartFile multipartFile) {
|
|
|
+ //选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 。
|
|
|
+ File file = null;
|
|
|
+ try {
|
|
|
+ String originalFilename = multipartFile.getOriginalFilename();
|
|
|
+ String[] filename = originalFilename.split("\\.");
|
|
|
+ file = File.createTempFile(filename[0], filename[1]);
|
|
|
+ multipartFile.transferTo(file);
|
|
|
+ file.deleteOnExit();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return file;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * File 转 MultipartFile
|
|
|
+ * @param file
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static MultipartFile fileToTransfer(File file) {
|
|
|
+ FileItem item = new DiskFileItemFactory().createItem("file"
|
|
|
+ , MediaType.MULTIPART_FORM_DATA_VALUE
|
|
|
+ , true
|
|
|
+ , file.getName());
|
|
|
+ try (InputStream input = new FileInputStream(file);
|
|
|
+ OutputStream os = item.getOutputStream()) {
|
|
|
+ // 流转移
|
|
|
+ IOUtils.copy(input, os);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new IllegalArgumentException("Invalid file: " + e, e);
|
|
|
+ }
|
|
|
+
|
|
|
+ return new CommonsMultipartFile(item);
|
|
|
+ }
|
|
|
+}
|