diff --git a/pom.xml b/pom.xml
index 8eb106a..198ec07 100644
--- a/pom.xml
+++ b/pom.xml
@@ -187,6 +187,18 @@
1.2.83_noneautotype
+
+
+ com.itextpdf
+ itextpdf
+ 5.5.10
+
+
+
+ com.itextpdf
+ itext-asian
+ 5.2.0
+
diff --git a/src/main/java/com/supervision/config/JwtInterceptor.java b/src/main/java/com/supervision/config/JwtInterceptor.java
index 2e8fd02..cd2e3e7 100644
--- a/src/main/java/com/supervision/config/JwtInterceptor.java
+++ b/src/main/java/com/supervision/config/JwtInterceptor.java
@@ -6,6 +6,7 @@ import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.supervision.utils.TokenUtil;
+import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
@@ -28,7 +29,7 @@ public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
//请求消息头获取用户ID
- String token = request.getHeader("token");
+ String token = findTokenInRequest(request);
if (StrUtil.isBlank(token)) {
// 如果是swagger来的接口,说明这里是测试的,会伪造一个用户
String referer = request.getHeader("Referer");
@@ -36,13 +37,24 @@ public class JwtInterceptor implements HandlerInterceptor {
cacheAuth(JWTUtil.parseToken(devActiveUser()));
return true;
} else {
-// throw new BusinessException("当前用户未登录", HttpStatus.UNAUTHORIZED.value());
+ throw new BusinessException("当前用户未登录", HttpStatus.UNAUTHORIZED.value());
}
}
-// JWT jwt = JWTUtil.parseToken(token);
+ JWT jwt = JWTUtil.parseToken(token);
// 校验token是否过期,如果过期了,需要提示过期重新登录
-// checkTokenExpire(jwt);
-// cacheAuth(jwt);
+ boolean expire = checkTokenExpire(jwt);
+ if (expire){
+ throw new BusinessException("用户登录已过期,请重新登录", HttpStatus.UNAUTHORIZED.value());
+ }
+ String cookieToken = findTokenInCookie(request.getCookies());
+ if (!StrUtil.equals(cookieToken, token)){
+ Cookie tokenCookie = new Cookie("token", token);
+ tokenCookie.setMaxAge((int) TokenUtil.EXPIRE_TIME);
+ tokenCookie.setPath("/");
+ tokenCookie.setAttribute("SameSite", "Lax");
+ response.addCookie(tokenCookie);
+ }
+ cacheAuth(jwt);
return true;
}
@@ -55,15 +67,38 @@ public class JwtInterceptor implements HandlerInterceptor {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
+ private String findTokenInRequest(HttpServletRequest request) {
+ String token = request.getHeader("token");
+ if (StrUtil.isEmpty(token)) {
+ // 尝试从cookie中获取token数据
+ token = findTokenInCookie(request.getCookies());
+ }
+ return token;
+ }
+
- private void checkTokenExpire(JWT jwt) {
+ private String findTokenInCookie(Cookie[] cookies) {
+ if (cookies != null) {
+ for (Cookie cookie : cookies) {
+ if (cookie.getName().equals("token")) {
+ return cookie.getValue();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 校验token是否过期
+ * @param jwt jwt
+ * @return true 过期,false未过期
+ */
+ private boolean checkTokenExpire(JWT jwt) {
Object expireTime = jwt.getPayload("expireTime");
long l = Long.parseLong(String.valueOf(expireTime));
// 校验是否比当前时间大
long currentTimeMillis = System.currentTimeMillis();
- if (currentTimeMillis > l) {
- throw new BusinessException("用户登录已过期,请重新登录", HttpStatus.UNAUTHORIZED.value());
- }
+ return currentTimeMillis > l;
}
diff --git a/src/main/java/com/supervision/config/WebConfig.java b/src/main/java/com/supervision/config/WebConfig.java
index c2d8151..58a9cf3 100644
--- a/src/main/java/com/supervision/config/WebConfig.java
+++ b/src/main/java/com/supervision/config/WebConfig.java
@@ -27,7 +27,7 @@ public class WebConfig implements WebMvcConfigurer {
paths.add("/error");
paths.add("/favicon.ico");
paths.add("/user/login");
- paths.add("/minio/downloadFile");
+ // paths.add("/minio/downloadFile");
paths.add("/minio/uploadFile");
paths.add("/user/changePassWord");
paths.add("/fileManage/downloadFile");
diff --git a/src/main/java/com/supervision/minio/service/MinioService.java b/src/main/java/com/supervision/minio/service/MinioService.java
index 404537d..0a6e524 100644
--- a/src/main/java/com/supervision/minio/service/MinioService.java
+++ b/src/main/java/com/supervision/minio/service/MinioService.java
@@ -17,6 +17,8 @@ public interface MinioService {
void downloadFile(String fileId, HttpServletResponse response);
+ void downloadFileWithWatermark(String fileId, String fileType, String waterMarkName, HttpServletResponse response);
+
R> delFile(String fileId);
InputStream getObjectInputStream(String fileId);
diff --git a/src/main/java/com/supervision/minio/service/impl/MinioServiceImpl.java b/src/main/java/com/supervision/minio/service/impl/MinioServiceImpl.java
index 2a36eb2..15a0728 100644
--- a/src/main/java/com/supervision/minio/service/impl/MinioServiceImpl.java
+++ b/src/main/java/com/supervision/minio/service/impl/MinioServiceImpl.java
@@ -1,23 +1,32 @@
package com.supervision.minio.service.impl;
import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.StrUtil;
+import com.itextpdf.text.DocumentException;
import com.supervision.common.domain.R;
import com.supervision.common.utils.StringUtils;
import com.supervision.minio.client.MinioTemplate;
import com.supervision.minio.domain.MinioFile;
import com.supervision.minio.mapper.MinioFileMapper;
import com.supervision.minio.service.MinioService;
+import com.supervision.utils.UserUtil;
+import com.supervision.utils.WatermarkUtil;
+import io.minio.StatObjectResponse;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
+@Slf4j
@Service
@RequiredArgsConstructor
public class MinioServiceImpl implements MinioService {
@@ -60,7 +69,42 @@ public class MinioServiceImpl implements MinioService {
public void downloadFile(String fileId, HttpServletResponse response) {
MinioFile minioFile = minioFileMapper.selectById(fileId);
String fileType = minioFile.getFileType();
- minioTemplate.getObject(bucketName, fileId, fileType, response);
+ this.downloadFileWithWatermark(fileId, fileType, UserUtil.getUser().getUserName(), response);
+ }
+
+
+ @Override
+ public void downloadFileWithWatermark(String fileId, String fileType, String waterMarkName, HttpServletResponse response) {
+ try {
+ InputStream inputStream = minioTemplate.getObjectInputStream(bucketName,fileId);
+
+ StatObjectResponse statObjectResponse = minioTemplate.statObject(bucketName, fileId);
+
+ String fileName = fileId + "." + fileType;
+ response.setHeader("Content-Disposition", "inline;filename=" + fileName);
+ response.setCharacterEncoding("UTF-8");
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ if (StrUtil.equalsIgnoreCase("pdf", fileType)){
+ WatermarkUtil.pdfByText(inputStream, baos, waterMarkName, Map.of());
+ response.setContentLengthLong(baos.size());
+ response.setContentType(statObjectResponse.contentType());
+ response.getOutputStream().write(baos.toByteArray());
+ }else if (StrUtil.equalsAnyIgnoreCase(fileType,"jpg", "jpeg", "png","bmp")){
+ WatermarkUtil.ImageByText(waterMarkName, inputStream, baos, Map.of("formatName", fileType));
+ response.setContentType(statObjectResponse.contentType());
+ response.setContentLengthLong(baos.size());
+ response.getOutputStream().write(baos.toByteArray());
+ }else {
+ response.setContentLengthLong(statObjectResponse.size());
+ response.setContentType(statObjectResponse.contentType());
+ IoUtil.copy(inputStream, response.getOutputStream());
+ }
+ baos.close();
+ inputStream.close();
+ }catch (IOException | DocumentException e){
+ log.error("文件下载失败", e);
+ }
}
@Override
diff --git a/src/main/java/com/supervision/police/controller/CaseEvidenceController.java b/src/main/java/com/supervision/police/controller/CaseEvidenceController.java
index 20be9dd..6700fce 100644
--- a/src/main/java/com/supervision/police/controller/CaseEvidenceController.java
+++ b/src/main/java/com/supervision/police/controller/CaseEvidenceController.java
@@ -2,6 +2,7 @@ package com.supervision.police.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
+import com.itextpdf.text.DocumentException;
import com.supervision.common.domain.R;
import com.supervision.police.domain.EvidenceDirectory;
import com.supervision.police.dto.*;
@@ -16,6 +17,8 @@ import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
import java.util.List;
@@ -195,7 +198,7 @@ public class CaseEvidenceController {
}
@GetMapping("/downloadEvidence")
- public void downloadEvidence(@RequestParam String evidenceId, HttpServletResponse response) {
+ public void downloadEvidence(@RequestParam String evidenceId, HttpServletResponse response) throws DocumentException, IOException {
caseEvidenceService.downloadEvidence(evidenceId, response);
}
diff --git a/src/main/java/com/supervision/police/service/CaseEvidenceService.java b/src/main/java/com/supervision/police/service/CaseEvidenceService.java
index 31ac6ab..a27f31a 100644
--- a/src/main/java/com/supervision/police/service/CaseEvidenceService.java
+++ b/src/main/java/com/supervision/police/service/CaseEvidenceService.java
@@ -2,6 +2,7 @@ package com.supervision.police.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
+import com.itextpdf.text.DocumentException;
import com.supervision.police.domain.CaseEvidence;
import com.supervision.police.domain.EvidenceDirectory;
import com.supervision.police.domain.EvidenceFile;
@@ -11,6 +12,8 @@ import com.supervision.police.vo.EvidenceDirectoryReqVO;
import com.supervision.police.vo.VerifyEvidenceReqVO;
import jakarta.servlet.http.HttpServletResponse;
+
+import java.io.IOException;
import java.util.List;
import java.util.Map;
@@ -165,5 +168,5 @@ public interface CaseEvidenceService extends IService {
void redoExtractAttributes(String caseId, List caseEvidences);
- void downloadEvidence(String evidenceId, HttpServletResponse response);
+ void downloadEvidence(String evidenceId, HttpServletResponse response) throws IOException, DocumentException;
}
diff --git a/src/main/java/com/supervision/police/service/impl/CaseEvidenceServiceImpl.java b/src/main/java/com/supervision/police/service/impl/CaseEvidenceServiceImpl.java
index 23f481c..11c2436 100644
--- a/src/main/java/com/supervision/police/service/impl/CaseEvidenceServiceImpl.java
+++ b/src/main/java/com/supervision/police/service/impl/CaseEvidenceServiceImpl.java
@@ -13,6 +13,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.itextpdf.text.DocumentException;
import com.supervision.common.constant.EvidenceConstants;
import com.supervision.common.constant.IndexRuleConstants;
import com.supervision.minio.domain.MinioFile;
@@ -23,6 +24,8 @@ import com.supervision.police.mapper.CaseEvidenceMapper;
import com.supervision.police.service.*;
import com.supervision.police.vo.EvidenceDirectoryReqVO;
import com.supervision.police.vo.VerifyEvidenceReqVO;
+import com.supervision.utils.UserUtil;
+import com.supervision.utils.WatermarkUtil;
import com.supervision.utils.ZipFileUtil;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
@@ -34,6 +37,8 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
@@ -956,15 +961,25 @@ public class CaseEvidenceServiceImpl extends ServiceImpl evidenceFileDTOList = evidenceFileService.listFileInfo(List.of(evidenceId));
Map fileInputStreamMap = new HashMap<>();
- evidenceFileDTOList.forEach(evidenceFileDTO -> {
+ for (EvidenceFileDTO evidenceFileDTO : evidenceFileDTOList) {
MinioFile minioFile = minioService.getMinioFile(evidenceFileDTO.getFileId());
if (null != minioFile) {
- fileInputStreamMap.put(minioFile.getFilename(), minioService.getObjectInputStream(minioFile));
+ if (StrUtil.equalsAnyIgnoreCase(minioFile.getFileType(), "pdf")) {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ WatermarkUtil.pdfByText(minioService.getObjectInputStream(minioFile), bos, UserUtil.getUser().getUserName(), Map.of());
+ fileInputStreamMap.put(minioFile.getFilename(), new ByteArrayInputStream(bos.toByteArray()));
+ } else if (StrUtil.equalsAnyIgnoreCase(minioFile.getFileType(), "jpg", "png", "jpeg", "bmp")) {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ WatermarkUtil.ImageByText(UserUtil.getUser().getUserName(), minioService.getObjectInputStream(minioFile), bos, Map.of("formatName", minioFile.getFileType()));
+ fileInputStreamMap.put(minioFile.getFilename(), new ByteArrayInputStream(bos.toByteArray()));
+ } else {
+ fileInputStreamMap.put(minioFile.getFilename(), minioService.getObjectInputStream(minioFile));
+ }
}
- });
+ }
try {
ZipFileUtil.createZipAndDownload(response, getById(evidenceId).getEvidenceName(), fileInputStreamMap);
} catch (IOException e) {
diff --git a/src/main/java/com/supervision/utils/TokenUtil.java b/src/main/java/com/supervision/utils/TokenUtil.java
index 5542884..c05c043 100644
--- a/src/main/java/com/supervision/utils/TokenUtil.java
+++ b/src/main/java/com/supervision/utils/TokenUtil.java
@@ -8,11 +8,13 @@ import cn.hutool.jwt.signers.JWTSignerUtil;
public class TokenUtil {
+ public static final long EXPIRE_TIME = 60 * 60 * 24;
+
public static String creatToken(String userInfo){
final JWTSigner signer = JWTSignerUtil.hs256("~~||DDEdfdfee33s6$$".getBytes());
JSONObject info = JSONUtil.parseObj(userInfo);
// 过期时间一天,同时这个字段也作为单点登录使用
- info.putOnce("expireTime",System.currentTimeMillis() + 1000 * 60 * 60 * 24);
+ info.putOnce("expireTime",System.currentTimeMillis() + 1000 * EXPIRE_TIME);
info.putOnce("issueTime",System.currentTimeMillis());
return JWTUtil.createToken(info, signer);
}
diff --git a/src/main/java/com/supervision/utils/UserUtil.java b/src/main/java/com/supervision/utils/UserUtil.java
index c726913..32fc5cd 100644
--- a/src/main/java/com/supervision/utils/UserUtil.java
+++ b/src/main/java/com/supervision/utils/UserUtil.java
@@ -1,32 +1,16 @@
package com.supervision.utils;
import cn.hutool.core.lang.Assert;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
-import cn.hutool.jwt.JWT;
-import cn.hutool.jwt.JWTUtil;
+import com.supervision.config.ThreadCache;
import com.supervision.police.dto.user.UserInfoDTO;
-import jakarta.servlet.http.HttpServletRequest;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
public class UserUtil {
public static UserInfoDTO getUser() {
- ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
- Assert.notNull(requestAttributes, "未获取到用户信息");
- HttpServletRequest request = requestAttributes.getRequest();
-
- String token = request.getHeader("token");
- if (StrUtil.isBlank(token)) {
- token = (String) request.getAttribute("token");
-
- }
- Assert.notEmpty(token, "未获取到用户token信息");
- JWT jwt = JWTUtil.parseToken(token);
- JSONObject claimsJson = jwt.getPayload().getClaimsJson();
- UserInfoDTO bean = JSONUtil.toBean(claimsJson.toString(), UserInfoDTO.class);
+
+ String userString = ThreadCache.USER.get();
+ UserInfoDTO bean = JSONUtil.toBean(userString, UserInfoDTO.class);
Assert.notNull(bean, "未获取到用户信息");
return bean;
}
diff --git a/src/main/java/com/supervision/utils/WatermarkUtil.java b/src/main/java/com/supervision/utils/WatermarkUtil.java
new file mode 100644
index 0000000..30a7eee
--- /dev/null
+++ b/src/main/java/com/supervision/utils/WatermarkUtil.java
@@ -0,0 +1,184 @@
+package com.supervision.utils;
+
+import com.itextpdf.text.DocumentException;
+import com.itextpdf.text.Element;
+import com.itextpdf.text.pdf.*;
+
+import javax.imageio.ImageIO;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.util.HashMap;
+import java.util.Map;
+
+public class WatermarkUtil {
+
+ private final static Map imageConfig = getImgDefaultConfig();
+
+ private final static Map pdfConfig = getPdfDefaultConfig();
+
+ public static Map getImgDefaultConfig(){
+
+ Map config = new HashMap<>();
+ config.put("alpha",0.5f); // 水印透明度
+ config.put("fontSize",28); // 水印文字大小
+ config.put("font",new Font("微软雅黑", Font.PLAIN, 28)); // 水印文字字体
+ config.put("color",Color.gray); // 水印文字颜色
+ config.put("xMove",80); // 水印之间的间隔
+ config.put("yMove",80); // 水印之间的间隔
+ config.put("degree",-40);// 旋转角度
+ config.put("formatName","JPG");
+ return config;
+ }
+
+
+ public static Map getPdfDefaultConfig(){
+ Map config = new HashMap<>();
+ try {
+ config.put("baseFont",BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED));
+ } catch ( IOException|DocumentException e) {
+ throw new RuntimeException(e);
+ }
+ config.put("fillOpacity",0.3f);// 填充透明度
+ config.put("strokeOpacity",0.4f);// 笔划不透明度
+ config.put("fontSize",16);//字体大小
+ config.put("interval",-15);// 水印间隔
+ config.put("rotation",30);// 旋转角度
+ return config;
+ }
+
+
+ /**
+ * 获取文本长度。汉字为1:1,英文和数字为2:1
+ */
+ private static int getTextLength(String text) {
+ int length = text.length();
+ for (int i = 0; i < text.length(); i++) {
+ String s = String.valueOf(text.charAt(i));
+ if (s.getBytes().length > 1) {
+ length++;
+ }
+ }
+ length = length % 2 == 0 ? length / 2 : length / 2 + 1;
+ return length;
+ }
+
+ public static void pdfByText(InputStream inputStream, OutputStream outputStream, String waterMarkName,Map config) throws DocumentException, IOException {
+ PdfReader reader = new PdfReader(inputStream);
+ PdfStamper stamper = new PdfStamper(reader, outputStream);
+ try {
+
+ BaseFont base = (BaseFont) config.getOrDefault("baseFont",pdfConfig.get("baseFont"));
+
+ com.itextpdf.text.Rectangle pageRect;
+ PdfGState gs = new PdfGState();
+ gs.setFillOpacity((Float) config.getOrDefault("fillOpacity",pdfConfig.get("fillOpacity")));
+ gs.setStrokeOpacity((Float) config.getOrDefault("strokeOpacity",pdfConfig.get("strokeOpacity")));
+ int total = reader.getNumberOfPages() + 1;
+
+ JLabel label = new JLabel();
+ FontMetrics metrics;
+ int textH;
+ int textW;
+ label.setText(waterMarkName);
+ metrics = label.getFontMetrics(label.getFont());
+ textH = metrics.getHeight();
+ textW = metrics.stringWidth(label.getText());
+
+ PdfContentByte under;
+ int interval = (int) config.getOrDefault("interval", pdfConfig.get("interval"));
+ int rotation = (int) config.getOrDefault("rotation", pdfConfig.get("rotation"));
+ int fontSize = (int) config.getOrDefault("fontSize", pdfConfig.get("fontSize"));
+ for (int i = 1; i < total; i++) {
+ pageRect = reader.getPageSizeWithRotation(i);
+ under = stamper.getOverContent(i);
+ under.saveState();
+ under.setGState(gs);
+ under.beginText();
+ under.setFontAndSize(base, fontSize);
+
+
+ for (int height = interval + textH; height < pageRect.getHeight(); height = height + textH * 3) {
+ for (int width = interval + textW; width < pageRect.getWidth() + textW; width = width + textW * 2) {
+ under.showTextAligned(Element.ALIGN_LEFT
+ , waterMarkName, width - textW, height - textH, rotation);
+ }
+ }
+ // 添加水印文字
+ under.endText();
+ }
+
+ } finally {
+ stamper.close();
+ reader.close();
+ }
+ }
+
+
+ /**
+ * 给图片添加水印文字、可设置水印文字的旋转角度
+ * @param logoText 水印文字
+ * @param inputStream
+ * @param outputStream
+ */
+ public static void ImageByText(String logoText, InputStream inputStream, OutputStream outputStream, Map config) throws IOException {
+
+ // 源图片
+ Image srcImg = ImageIO.read(inputStream);
+
+ // 原图宽度
+ int width = srcImg.getWidth(null);
+
+ // 原图高度
+ int height = srcImg.getHeight(null);
+
+ BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null), srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
+ // 构建画笔对象
+ Graphics2D g = buffImg.createGraphics();
+ try {
+
+ // 设置对线段的锯齿状边缘处理
+ 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);
+ // 设置水印旋转
+ Integer degree = (Integer) config.getOrDefault("degree", imageConfig.get("degree"));
+ if (null != degree) {
+ g.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);
+ }
+ // 设置水印文字颜色
+ g.setColor((Color) config.getOrDefault("color", imageConfig.get("color")));
+ // 设置水印文字Font
+ g.setFont((Font) config.getOrDefault("font", imageConfig.get("font")));
+ // 设置水印文字透明度
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, (Float) config.getOrDefault("alpha", imageConfig.get("alpha"))));
+
+ int x = -width / 2;
+ int y;
+
+ // 字体高度
+ int markHeight = (int) config.getOrDefault("fontSize", imageConfig.get("fontSize"));
+
+ // 字体长度
+ int markWidth = markHeight * getTextLength(logoText);
+
+ // 循环添加水印
+ while (x < width * 1.5) {
+ y = -height / 2;
+ while (y < height * 1.5) {
+ g.drawString(logoText, x, y);
+ y += markHeight + (int) config.getOrDefault("yMove", imageConfig.get("yMove"));
+ }
+ x += markWidth + (int) config.getOrDefault("xMove", imageConfig.get("xMove"));
+ }
+ } finally {
+ // 释放资源
+ g.dispose();
+ }
+
+ // 生成图片
+ ImageIO.write(buffImg, (String) config.getOrDefault("formatName", imageConfig.get("formatName")), outputStream);
+
+ }
+
+}
diff --git a/src/test/java/com/supervision/demo/WordRenderTest.java b/src/test/java/com/supervision/demo/WordRenderTest.java
index 8da54ae..396b961 100644
--- a/src/test/java/com/supervision/demo/WordRenderTest.java
+++ b/src/test/java/com/supervision/demo/WordRenderTest.java
@@ -12,7 +12,7 @@ import org.springframework.boot.test.context.SpringBootTest;
import java.io.*;
import java.util.HashMap;
-
+import java.io.IOException;
@Slf4j
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class WordRenderTest {
@@ -23,7 +23,7 @@ public class WordRenderTest {
@Autowired
private ModelService modelService;
- public static void main(String[] args) throws FileNotFoundException {
+ public static void main1(String[] args) throws FileNotFoundException {
HashMap data = new HashMap<>();
data.put("name", "张三");
@@ -42,6 +42,86 @@ public class WordRenderTest {
}
//裴金禄涉嫌合同诈骗案详情-v0.docx
+ public static void main(String[] args) {
+
+ }
+
+ /*ublic static void main(String[] args) {
+
+ try {
+ //水印文字
+ String str = "裴金禄";
+ // 原图片的路径
+ File inputImage = new File("F:\\tmp\\1\\赵耀文第一次\\赵耀文第一次-1.jpg");
+ // 输出图片的路径
+ File outputImage = new File("F:\\tmp\\1\\赵耀文第一次\\赵耀文第一次-水印.jpg");
+
+ // 构建一个image对象
+ BufferedImage img = ImageIO.read(inputImage);
+ int width = img.getWidth();
+ int height = img.getHeight();
+
+ // 计算字体大小
+ int fontSize = (width + height) / 80;
+
+ Graphics2D g = img.createGraphics();
+ g.setFont(new Font("黑体", Font.PLAIN, fontSize));
+ g.setColor(new Color(0, 0, 0, 30));
+
+ // 旋转角度
+ g.rotate(-0.6);
+
+ // 间隔
+ int split = fontSize * 2;
+ // 文字占用的宽度
+ int xWidth = getStrWidth(str, fontSize);
+ // x,y可以绘制的数量,多加一个补充空白
+ int xCanNum = width / xWidth + 1;
+ int yCanNum = height / fontSize + 1;
+ for (int i = 1; i <= yCanNum; i++) {
+ int y = fontSize * i + split * i;
+ for (int j = 0; j < xCanNum; j++) {
+ int x = xWidth * j + split * j;
+ g.drawString(str, x, y - (fontSize + split) * j);
+ }
+ }
+ g.dispose();
+ ImageIO.write(img, "png", outputImage);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }*/
+
+
+
+ /**
+ * 获取字符串占用的宽度
+ *
+ * @param str 字符串
+ * @param fontSize 文字大小
+ * @return 字符串占用的宽度
+ */
+ public static int getStrWidth(String str, int fontSize) {
+ char[] chars = str.toCharArray();
+ int fontSize2 = fontSize / 2;
+
+ int width = 0;
+
+ for (char c : chars) {
+ int len = String.valueOf(c).getBytes().length;
+ // 汉字为3,其余1
+ // 可能还有一些特殊字符占用2 等等,统统计为汉字·
+ if (len != 1) {
+ width += fontSize;
+ } else {
+ width += fontSize2;
+ }
+ }
+ return width;
+ }
+
+
@Test
public void test() throws FileNotFoundException {
CaseScoreDetailDTO caseScoreDetailDTO = modelService.caseScoreDetail("1810902613967384577");