From 5f20fc02cb6873ceabde9f34cf62967bbd92d82f Mon Sep 17 00:00:00 2001
From: peter <14100000001@qq.com>
Date: Sun, 11 Jan 2026 02:10:33 +0800
Subject: [PATCH] 签章

---
 src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java |  387 +++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 291 insertions(+), 96 deletions(-)

diff --git a/src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java b/src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java
index 7a78c5c..88a9f23 100644
--- a/src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/UserAgreementServiceImpl.java
@@ -31,6 +31,8 @@
 import java.util.List;
 import java.awt.Graphics2D;
 import java.awt.RenderingHints;
+import java.awt.Color;
+import java.awt.FontMetrics;
 import com.nq.pojo.ContractImage;
 import com.nq.dao.ContractImageMapper;
 import com.alibaba.fastjson.JSON;
@@ -70,9 +72,9 @@
 
             String pdfFileName = "agreement_" + user.getId() + ".pdf";
             File pdfFile = new File(dir, pdfFileName);
-            
+
             // 构建完整的PDF访问URL
-            String pdfUrl = PropertiesUtil.getProperty("pdf.server.http.prefix") + "/agreement_" + user.getId() + ".pdf";
+//            String pdfUrl = PropertiesUtil.getProperty("pdf.server.http.prefix") + "/agreement_" + user.getId() + ".pdf";
 
             // 如果PDF已存在,删除后重新生成,确保数据是最新的
             if (pdfFile.exists()) {
@@ -94,32 +96,36 @@
 
             // 将PDF转换为图片并返回图片路径数组
             List<String> imageUrls = convertPdfToImages(pdfFile, "contract", user.getId());
-            
+
             return ServerResponse.createBySuccess(imageUrls);
         } catch (Exception e) {
             log.error("生成用户协议PDF失败", e);
             return ServerResponse.createByErrorMsg("生成PDF失败:" + e.getMessage());
         }
     }
+
     /**
      * 从PDF模板生成新的PDF,替换占位符
      */
     private void generatePdfFromTemplate(File templatePdf, File outputPdf, User user) throws Exception {
-        log.info("开始生成PDF,模板路径: {}, 输出路径: {}, 用户: {}", 
+        log.info("开始生成PDF,模板路径: {}, 输出路径: {}, 用户: {}",
                 templatePdf.getAbsolutePath(), outputPdf.getAbsolutePath(), user.getId());
-        
+
         PdfReader reader = null;
         PdfStamper stamper = null;
         FileOutputStream fos = null;
-        
+
         try {
             reader = new PdfReader(new FileInputStream(templatePdf));
             fos = new FileOutputStream(outputPdf);
             stamper = new PdfStamper(reader, fos);
 
-            // 设置中文字体
-            BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
+            // 设置中文字体,使用EMBEDDED确保字体嵌入PDF,避免转图片时乱码
+            // 使用itext-asian库提供的中文字体,必须使用EMBEDDED模式
+            BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
             Font font = new Font(baseFont, 12, Font.NORMAL);
+
+            log.info("中文字体已加载: {}", baseFont.getPostscriptFontName());
 
             SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
             String currentDate = sdf.format(new Date());
@@ -128,7 +134,7 @@
             String realName = user.getRealName() != null ? user.getRealName() : "";
             String idCard = user.getIdCard() != null ? user.getIdCard() : "";
             String address = user.getRegAddress() != null ? user.getRegAddress() : "";
-            
+
             log.info("PDF生成数据 - 姓名: {}, 身份证: {}, 地址: {}", realName, idCard, address);
 
             // 获取PDF页数
@@ -154,7 +160,7 @@
             reader = null;
             fos.close();
             fos = null;
-            
+
             // 验证生成的文件
             if (outputPdf.exists()) {
                 long fileSize = outputPdf.length();
@@ -194,49 +200,157 @@
     }
 
     /**
-     * 在PDF上替换占位符(使用文本覆盖方式)
+     * 在PDF上替换占位符(使用透明背景图片方式)
      */
     private void replacePlaceholdersInPdf(PdfContentByte canvas, Rectangle pageSize, String pageText,
-                                         String realName, String idCard, String address, 
-                                         String currentDate, Font font,int pageNum) throws Exception {
-        // 查找占位符在文本中的位置,然后估算在PDF中的坐标
-        // 由于PDF坐标系统复杂,这里使用固定位置替换
-        // 实际使用时需要根据PDF模板的具体布局调整坐标
+                                          String realName, String idCard, String address,
+                                          String currentDate, Font font,int pageNum) throws Exception {
         float margin = 50;
         float lineHeight = 14;
-        float startY = pageSize.getHeight() - 194;
+        float startY = pageSize.getHeight() - 204;
 
         if(pageNum == 1){
-            replacePlaceholder(canvas, "", realName, margin + 75, startY, 0, font);
+            // 生成透明背景的姓名图片并插入
+            File nameImage = createTextImage(realName, font);
+            insertImageToPdf(canvas, nameImage, margin + 75, startY);
             startY -= lineHeight;
 
-            replacePlaceholder(canvas, "", address, margin + 75, startY-2, 0, font);
+            // 生成透明背景的地址图片并插入
+            File addressImage = createTextImage(address, font);
+            insertImageToPdf(canvas, addressImage, margin + 75, startY-2);
             startY -= lineHeight;
 
-            replacePlaceholder(canvas, "", idCard, margin + 95, startY-2, 0, font);
+            // 生成透明背景的身份证号图片并插入
+            File idCardImage = createTextImage(idCard, font);
+            insertImageToPdf(canvas, idCardImage, margin + 95, startY-2);
         }
         if(pageNum == 3){
-            replacePlaceholder(canvas, "", currentDate, margin + 60, startY+32, 0, font);
-            replacePlaceholder(canvas, "", currentDate, margin + 60, startY, 0, font);
+            // 生成透明背景的日期图片并插入
+            File dateImage1 = createTextImage(currentDate, font);
+            insertImageToPdf(canvas, dateImage1, margin + 60, startY+32);
+            
+            File dateImage2 = createTextImage(currentDate, font);
+            insertImageToPdf(canvas, dateImage2, margin + 60, startY);
         }
-
     }
 
     /**
-     * 替换单个占位符
+     * 创建透明背景的文本图片
      */
-    private void replacePlaceholder(PdfContentByte canvas, String placeholder, String value,
-                                   float x, float y, float width, Font font) {
-        // 添加白色背景覆盖占位符区域
-        canvas.saveState();
-        canvas.setColorFill(BaseColor.WHITE);
-        canvas.rectangle(x - 5, y - 15, width, 20);
-        canvas.fill();
-        canvas.restoreState();
+    private File createTextImage(String text, Font font) throws Exception {
+        if (StringUtils.isBlank(text)) {
+            text = "";
+        }
 
-        // 添加新文本
-        ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT,
-                new Phrase(value, font), x, y, 0);
+        // 创建临时文件
+        String tempDir = PropertiesUtil.getProperty("loca.pdf.dir");
+        File dir = new File(tempDir);
+        if (!dir.exists()) {
+            dir.mkdirs();
+        }
+        
+        String tempFileName = "text_" + System.currentTimeMillis() + "_" + Thread.currentThread().getId() + ".png";
+        File imageFile = new File(dir, tempFileName);
+
+        // 创建透明背景的BufferedImage (TYPE_INT_ARGB 默认透明)
+        BufferedImage image = new BufferedImage(500, 50, BufferedImage.TYPE_INT_ARGB);
+        Graphics2D g2d = image.createGraphics();
+        
+        // 启用透明背景支持
+        g2d.setComposite(java.awt.AlphaComposite.SrcOver);
+
+        // 设置高质量渲染
+        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
+        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+        g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
+
+        // 设置字体和颜色
+        try {
+            java.awt.Font awtFont = new java.awt.Font("SimSun", java.awt.Font.PLAIN, 12);
+            g2d.setFont(awtFont);
+        } catch (Exception e) {
+            log.warn("无法加载SimSun字体,使用默认字体", e);
+            g2d.setFont(new java.awt.Font(java.awt.Font.SANS_SERIF, java.awt.Font.PLAIN, 12));
+        }
+        // 使用深黑色,RGB(0, 0, 0) 完全不透明
+        g2d.setColor(new Color(0, 0, 0, 255));
+
+        // 绘制文本
+        FontMetrics fm = g2d.getFontMetrics();
+        int textWidth = fm.stringWidth(text);
+        int textHeight = fm.getHeight();
+        
+        // 调整图片大小以适应文本
+        if (textWidth > 0 && textHeight > 0) {
+            // TYPE_INT_ARGB 类型默认透明背景,不需要清除
+            BufferedImage resizedImage = new BufferedImage(textWidth + 20, textHeight + 10, BufferedImage.TYPE_INT_ARGB);
+            Graphics2D g2dResized = resizedImage.createGraphics();
+            
+            // 启用透明背景支持
+            g2dResized.setComposite(java.awt.AlphaComposite.SrcOver);
+            
+            // 设置高质量渲染
+            g2dResized.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+            g2dResized.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
+            g2dResized.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+            g2dResized.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
+            
+            // 设置字体
+            try {
+                java.awt.Font awtFont = new java.awt.Font("SimSun", java.awt.Font.PLAIN, 12);
+                g2dResized.setFont(awtFont);
+            } catch (Exception e) {
+                g2dResized.setFont(new java.awt.Font(java.awt.Font.SANS_SERIF, java.awt.Font.PLAIN, 12));
+            }
+            // 使用深黑色,RGB(0, 0, 0) 完全不透明
+            g2dResized.setColor(new Color(0, 0, 0, 255));
+            
+            // 绘制文本
+            g2dResized.drawString(text, 10, textHeight);
+            g2dResized.dispose();
+            
+            // 保存图片
+            ImageIO.write(resizedImage, "PNG", imageFile);
+            image = resizedImage;
+        } else {
+            // 如果文本为空,创建一个小的透明图片
+            BufferedImage emptyImage = new BufferedImage(50, 20, BufferedImage.TYPE_INT_ARGB);
+            ImageIO.write(emptyImage, "PNG", imageFile);
+            image = emptyImage;
+        }
+
+        g2d.dispose();
+
+        log.info("已创建透明背景文本图片: {}, 文本: {}", imageFile.getAbsolutePath(), text);
+        return imageFile;
+    }
+
+    /**
+     * 将图片插入到PDF指定位置
+     */
+    private void insertImageToPdf(PdfContentByte canvas, File imageFile, float x, float y) throws Exception {
+        if (imageFile == null || !imageFile.exists()) {
+            log.warn("图片文件不存在: {}", imageFile);
+            return;
+        }
+
+        try {
+            Image image = Image.getInstance(imageFile.getAbsolutePath());
+            image.setAbsolutePosition(x, y);
+            canvas.addImage(image);
+            log.info("图片已插入到PDF,位置: ({}, {})", x, y);
+            
+            // 删除临时图片文件
+            try {
+                imageFile.delete();
+            } catch (Exception e) {
+                log.warn("删除临时图片文件失败: {}", imageFile.getAbsolutePath(), e);
+            }
+        } catch (Exception e) {
+            log.error("插入图片到PDF失败: {}", imageFile.getAbsolutePath(), e);
+            throw e;
+        }
     }
 
     @Override
@@ -258,7 +372,7 @@
             }
 
             List<String> imageUrls = convertPdfToImages(pdfFile, "contract", user.getId());
-            
+
             response.setContentType("application/json;charset=UTF-8");
             response.getWriter().write(JSON.toJSONString(ServerResponse.createBySuccess(imageUrls)));
             response.getWriter().flush();
@@ -294,23 +408,23 @@
 
             String signatureFileName = "signature_" + user.getId() + ".png";
             File signatureFileLocal = new File(dir, signatureFileName);
-            
+
             signatureFile.transferTo(signatureFileLocal);
-            
+
             log.info("用户{}的签名图片已保存: {}", user.getId(), signatureFileLocal.getAbsolutePath());
-            
+
             String pdfDir = PropertiesUtil.getProperty("loca.pdf.dir");
             String pdfFileName = "agreement_" + user.getId() + ".pdf";
             File pdfFile = new File(pdfDir, pdfFileName);
-            
+
             if (pdfFile.exists()) {
                 addSignatureToPdf(pdfFile, signatureFileLocal, user);
-                
+
                 List<String> imageUrls = convertPdfToImages(pdfFile, "contract", user.getId());
-                
+
                 String imagePrefix = PropertiesUtil.getProperty("pdf.server.http.prefix");
                 long timestamp = System.currentTimeMillis();
-                
+
                 for (int i = 0; i < imageUrls.size(); i++) {
                     String imageName;
                     if (i == 0) {
@@ -319,7 +433,7 @@
                         imageName = "contract_" + timestamp + "_" + (i + 1) + ".png";
                     }
                     String imagePath = imagePrefix + "/" + imageName;
-                    
+
                     ContractImage contractImage = new ContractImage();
                     contractImage.setUserId(user.getId());
                     contractImage.setContractType("contract");
@@ -327,7 +441,7 @@
                     contractImage.setAddTime(new Date());
                     contractImageMapper.insert(contractImage);
                 }
-                
+
                 iUserService.updateSignedContract(user.getId(), "Y");
             }
             return ServerResponse.createBySuccessMsg("签名保存成功");
@@ -346,12 +460,12 @@
         PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(tempPdf));
 
         int pageCount = reader.getNumberOfPages();
-        
+
         // 在第三页插入签名图片
         if (pageCount >= 3) {
             PdfContentByte canvas = stamper.getOverContent(3);
             Rectangle pageSize = reader.getPageSize(3);
-            
+
             // 添加签名图片
             if (signatureImage.exists()) {
                 Image image = Image.getInstance(signatureImage.getAbsolutePath());
@@ -366,7 +480,7 @@
 
         stamper.close();
         reader.close();
-        
+
         // 替换原PDF文件
         if (tempPdf.exists()) {
             pdfFile.delete();
@@ -396,7 +510,7 @@
 
             String pdfFileName = "contract_" + user.getId() + ".pdf";
             File pdfFile = new File(dir, pdfFileName);
-            
+
             String pdfUrl = PropertiesUtil.getProperty("pdf.server.http.prefix") + "/contract_" + user.getId() + ".pdf";
 
             if (pdfFile.exists()) {
@@ -416,7 +530,7 @@
 
             // 将PDF转换为图片并返回图片路径数组
             List<String> imageUrls = convertPdfToImages(pdfFile, "agreement", user.getId());
-            
+
             return ServerResponse.createBySuccess(imageUrls);
         } catch (Exception e) {
             log.error("生成用户合同PDF失败", e);
@@ -443,7 +557,7 @@
             }
 
             List<String> imageUrls = convertPdfToImages(pdfFile, "agreement", user.getId());
-            
+
             response.setContentType("application/json;charset=UTF-8");
             response.getWriter().write(JSON.toJSONString(ServerResponse.createBySuccess(imageUrls)));
             response.getWriter().flush();
@@ -479,23 +593,23 @@
 
             String signatureFileName = "contract_signature_" + user.getId() + ".png";
             File signatureFileLocal = new File(dir, signatureFileName);
-            
+
             signatureFile.transferTo(signatureFileLocal);
-            
+
             log.info("用户{}的合同签名图片已保存: {}", user.getId(), signatureFileLocal.getAbsolutePath());
-            
+
             String pdfDir = PropertiesUtil.getProperty("loca.pdf.dir");
             String pdfFileName = "contract_" + user.getId() + ".pdf";
             File pdfFile = new File(pdfDir, pdfFileName);
-            
+
             if (pdfFile.exists()) {
                 addSignatureToContractPdf(pdfFile, signatureFileLocal, user);
-                
+
                 List<String> imageUrls = convertPdfToImages(pdfFile, "agreement", user.getId());
-                
+
                 String imagePrefix = PropertiesUtil.getProperty("pdf.server.http.prefix");
                 long timestamp = System.currentTimeMillis();
-                
+
                 for (int i = 0; i < imageUrls.size(); i++) {
                     String imageName;
                     if (i == 0) {
@@ -504,7 +618,7 @@
                         imageName = "agreement_" + timestamp + "_" + (i + 1) + ".png";
                     }
                     String imagePath = imagePrefix + "/" + imageName;
-                    
+
                     ContractImage contractImage = new ContractImage();
                     contractImage.setUserId(user.getId());
                     contractImage.setContractType("agreement");
@@ -512,10 +626,10 @@
                     contractImage.setAddTime(new Date());
                     contractImageMapper.insert(contractImage);
                 }
-                
+
                 iUserService.updateSignedAgreement(user.getId(), "Y");
             }
-            
+
             return ServerResponse.createBySuccessMsg("签名保存成功");
         } catch (Exception e) {
             log.error("保存用户合同签名失败", e);
@@ -527,11 +641,12 @@
         PdfReader reader = new PdfReader(new FileInputStream(templatePdf));
         PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputPdf));
 
-        BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
+        // 设置中文字体,使用EMBEDDED确保字体嵌入PDF,避免转图片时乱码
+        BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
         Font font = new Font(baseFont, 12, Font.NORMAL);
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
         String currentDate = sdf.format(new Date());
-        
+
         int pageCount = reader.getNumberOfPages();
 
         for (int pageNum = 1; pageNum <= pageCount; pageNum++) {
@@ -549,7 +664,9 @@
         float margin = 50;
         float startY = pageSize.getHeight() - 364;
         if(pageNum == 2){
-            replacePlaceholder(canvas, "", currentDate, margin + 320, startY, 0, font);
+            // 生成透明背景的日期图片并插入
+            File dateImage = createTextImage(currentDate, font);
+            insertImageToPdf(canvas, dateImage, margin + 320, startY);
         }
     }
 
@@ -559,11 +676,11 @@
         PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(tempPdf));
 
         int pageCount = reader.getNumberOfPages();
-        
+
         if (pageCount >= 2) {
             PdfContentByte canvas = stamper.getOverContent(2);
             Rectangle pageSize = reader.getPageSize(2);
-            
+
             if (signatureImage.exists()) {
                 Image image = Image.getInstance(signatureImage.getAbsolutePath());
                 image.scaleToFit(100, 100);
@@ -575,7 +692,7 @@
 
         stamper.close();
         reader.close();
-        
+
         if (tempPdf.exists()) {
             pdfFile.delete();
             tempPdf.renameTo(pdfFile);
@@ -593,19 +710,19 @@
                 log.error("PDF模板目录配置不存在: pdf.template.dir");
                 return null;
             }
-            
+
             File dir = new File(templateDir);
             if (!dir.exists()) {
                 log.error("PDF模板目录不存在: {}", templateDir);
                 return null;
             }
-            
+
             File templateFile = new File(dir, templateFileName);
             if (!templateFile.exists()) {
                 log.error("PDF模板文件不存在: {}", templateFile.getAbsolutePath());
                 return null;
             }
-            
+
             log.info("使用模板文件: {}", templateFile.getAbsolutePath());
             return templateFile;
         } catch (Exception e) {
@@ -614,44 +731,54 @@
         }
     }
 
+    public static void main(String[] args) {
+        try {
+            String pdfDir = "D:/work/A-stock/agreement_pdf";
+            String pdfFileName = "agreement_" + 19998 + ".pdf";
+            File pdfFile = new File(pdfDir, pdfFileName);
+            convertPdfToImages1(pdfFile,"agreement");
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
     /**
      * 将PDF转换为图片
      */
-    private List<String> convertPdfToImages(File pdfFile, String contractType, Integer userId) throws Exception {
+    public static void convertPdfToImages1(File pdfFile, String contractType) throws Exception {
         List<String> imageUrls = new ArrayList<>();
-        String imagePrefix = PropertiesUtil.getProperty("pdf.server.http.prefix");
-        String pdfDir = PropertiesUtil.getProperty("loca.pdf.dir");
-        
+        String imagePrefix = "http://localhost:8099";
+        String pdfDir = "D:/work/A-stock/agreement_pdf";
+
         long timestamp = System.currentTimeMillis();
         PDDocument document = null;
         try {
             document = PDDocument.load(pdfFile);
-            
+
             // 创建PDFRenderer,使用高质量渲染
             PDFRenderer pdfRenderer = new PDFRenderer(document);
-            
+
             int pageCount = document.getNumberOfPages();
             log.info("PDF总页数: {}", pageCount);
-            
+
             for (int page = 0; page < pageCount; page++) {
                 // 使用RGB模式渲染,DPI设置为300确保文字清晰
                 // ImageType.RGB可以更好地处理中文字体
                 BufferedImage image = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
-                
+
                 // 对图片进行优化处理,确保文字清晰
-                BufferedImage optimizedImage = optimizeImage(image);
-                
+                BufferedImage optimizedImage = optimizeImage1(image);
+
                 String imageFileName = contractType + "_" + timestamp + ".png";
                 if (page > 0) {
                     imageFileName = contractType + "_" + timestamp + "_" + (page + 1) + ".png";
                 }
                 File imageFile = new File(pdfDir, imageFileName);
-                
+
                 ImageIO.write(optimizedImage, "png", imageFile);
-                
+
                 String imageUrl = imagePrefix + "/imgs/" + imageFileName;
                 imageUrls.add(imageUrl);
-                
+
                 log.info("PDF第{}页已转换为图片: {}", page + 1, imageUrl);
             }
         } finally {
@@ -659,30 +786,98 @@
                 document.close();
             }
         }
-        
-        return imageUrls;
+
+//        return imageUrls;
     }
-    
-    /**
-     * 优化图片,确保文字清晰
-     */
-    private BufferedImage optimizeImage(BufferedImage originalImage) {
+
+    public static BufferedImage optimizeImage1(BufferedImage originalImage) {
         int width = originalImage.getWidth();
         int height = originalImage.getHeight();
-        
+
         BufferedImage optimizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
         Graphics2D g2d = optimizedImage.createGraphics();
-        
+
         // 设置高质量渲染
         g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
         g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
         g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
         g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
         g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
-        
+
         g2d.drawImage(originalImage, 0, 0, null);
         g2d.dispose();
-        
+
+        return optimizedImage;
+    }
+    /**
+     * 将PDF转换为图片
+     */
+    private List<String> convertPdfToImages(File pdfFile, String contractType, Integer userId) throws Exception {
+        List<String> imageUrls = new ArrayList<>();
+        String imagePrefix = PropertiesUtil.getProperty("pdf.server.http.prefix");
+        String pdfDir = PropertiesUtil.getProperty("loca.pdf.dir");
+
+        long timestamp = System.currentTimeMillis();
+        PDDocument document = null;
+        try {
+            document = PDDocument.load(pdfFile);
+
+            // 创建PDFRenderer,使用高质量渲染
+            PDFRenderer pdfRenderer = new PDFRenderer(document);
+
+            int pageCount = document.getNumberOfPages();
+            log.info("PDF总页数: {}", pageCount);
+
+            for (int page = 0; page < pageCount; page++) {
+                // 使用RGB模式渲染,DPI设置为300确保文字清晰
+                // ImageType.RGB可以更好地处理中文字体
+                BufferedImage image = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
+
+                // 对图片进行优化处理,确保文字清晰
+                BufferedImage optimizedImage = optimizeImage(image);
+
+                String imageFileName = contractType + "_" + timestamp + ".png";
+                if (page > 0) {
+                    imageFileName = contractType + "_" + timestamp + "_" + (page + 1) + ".png";
+                }
+                File imageFile = new File(pdfDir, imageFileName);
+
+                ImageIO.write(optimizedImage, "png", imageFile);
+
+                String imageUrl = imagePrefix + "/imgs/" + imageFileName;
+                imageUrls.add(imageUrl);
+
+                log.info("PDF第{}页已转换为图片: {}", page + 1, imageUrl);
+            }
+        } finally {
+            if (document != null) {
+                document.close();
+            }
+        }
+
+        return imageUrls;
+    }
+
+    /**
+     * 优化图片,确保文字清晰
+     */
+    private BufferedImage optimizeImage(BufferedImage originalImage) {
+        int width = originalImage.getWidth();
+        int height = originalImage.getHeight();
+
+        BufferedImage optimizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+        Graphics2D g2d = optimizedImage.createGraphics();
+
+        // 设置高质量渲染
+        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+        g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+
+        g2d.drawImage(originalImage, 0, 0, null);
+        g2d.dispose();
+
         return optimizedImage;
     }
 
@@ -699,7 +894,7 @@
             for (ContractImage image : images) {
                 imageUrls.add(image.getAddress());
             }
-            
+
             return ServerResponse.createBySuccess(imageUrls);
         } catch (Exception e) {
             log.error("查询合同图片列表失败", e);
@@ -720,7 +915,7 @@
             for (ContractImage image : images) {
                 imageUrls.add(image.getAddress());
             }
-            
+
             return ServerResponse.createBySuccess(imageUrls);
         } catch (Exception e) {
             log.error("查询保密协议图片列表失败", e);

--
Gitblit v1.9.3