package com.bcxin.backend.utils; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.ImageType; import org.apache.pdfbox.rendering.PDFRenderer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; public class DocumentFileUtil { private static final Logger logger = LoggerFactory.getLogger(DocumentFileUtil.class); // 添加最小印章像素阈值(例如:50x50 像素) private static final int MIN_SEAL_PIXELS = 50 * 50; public static boolean checkPdfForRedSeal( String rootPath, String filePath) { try { Path pdfPath = Paths.get(rootPath + filePath); File file = pdfPath.toFile(); if (!file.exists()) { logger.error("文件不存在: {}", pdfPath); return false; } try (PDDocument document = PDDocument.load(file)) { PDFRenderer pdfRenderer = new PDFRenderer(document); BufferedImage image = pdfRenderer.renderImageWithDPI(0, 300, ImageType.RGB); int width = image.getWidth(); int height = image.getHeight(); // 使用二维数组记录已访问的像素点 boolean[][] visited = new boolean[height][width]; int minSealDetected = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (visited[y][x]) continue; int rgb = image.getRGB(x, y); int r = (rgb >> 16) & 0xFF; int g = (rgb >> 8) & 0xFF; int b = rgb & 0xFF; // 判断是否为红色像素 if (r > 150 && g < 100 && b < 100) { // 使用广度优先搜索查找连通区域 int areaSize = floodFill(image, x, y, visited, width, height); if (areaSize > MIN_SEAL_PIXELS) { logger.info("发现疑似红色印章,面积:{}", areaSize); minSealDetected++; } } } } return minSealDetected > 0; } catch (IOException e) { logger.error("读取PDF文件失败: {}", filePath, e); } } catch (Exception ex) { logger.error("checkPdfForRedSeal: 执行失败:filePath={}", filePath, ex); } return false; } private static int floodFill(BufferedImage image, int startX, int startY, boolean[][] visited, int width, int height) { int count = 0; java.util.Queue queue = new java.util.LinkedList<>(); queue.add(new int[]{startX, startY}); visited[startY][startX] = true; while (!queue.isEmpty()) { int[] point = queue.poll(); int x = point[0]; int y = point[1]; count++; // 检查上下左右四个方向 for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { if (dx == 0 && dy == 0) continue; int nx = x + dx; int ny = y + dy; if (nx >= 0 && nx < width && ny >= 0 && ny < height && !visited[ny][nx]) { int rgb = image.getRGB(nx, ny); int r = (rgb >> 16) & 0xFF; int g = (rgb >> 8) & 0xFF; int b = rgb & 0xFF; if (r > 150 && g < 100 && b < 100) { visited[ny][nx] = true; queue.add(new int[]{nx, ny}); } } } } } return count; } }