package com.xly.ocr.service; import com.xly.ocr.util.OcrUtil; 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.util.Arrays; import java.util.List; @Slf4j @Service("ocrService") public class OcrService { @Value("${ocr.tmpPath}") private String tmpPath; private static final List ALLOWED_EXTENSIONS = Arrays.asList( ".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".gif" ); private static final long MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB /** * 从 MultipartFile 中提取文字 */ public String extractTextFromMultipartFile(MultipartFile file) { // 1. 验证文件 String validationError = validateFile(file); if (validationError != null) { return validationError; } // 2. 调用 OCR 工具类识别 try { String result = OcrUtil.ocrFile(file, tmpPath); if (result == null || result.trim().isEmpty()) { log.warn("未识别到文字内容,文件: {}", file.getOriginalFilename()); return "未识别到文字内容"; } log.info("识别成功,文件: {}, 文字长度: {}", file.getOriginalFilename(), result.length()); return result; } catch (Exception e) { log.error("OCR识别异常: {}", e.getMessage(), e); return "OCR识别失败: " + e.getMessage(); } } /** * 验证文件 */ private String validateFile(MultipartFile file) { if (file == null || file.isEmpty()) { log.warn("上传的文件为空"); return "上传的文件为空"; } if (file.getSize() > MAX_FILE_SIZE) { log.warn("文件过大: {} bytes", file.getSize()); return String.format("文件过大,最大支持 %dMB", MAX_FILE_SIZE / 1024 / 1024); } String originalFilename = file.getOriginalFilename(); if (originalFilename != null && !isAllowedImage(originalFilename)) { log.warn("不支持的文件格式: {}", originalFilename); return "不支持的文件格式,仅支持: " + String.join(", ", ALLOWED_EXTENSIONS); } return null; } /** * 检查文件扩展名是否允许 */ private boolean isAllowedImage(String filename) { if (filename == null) { return false; } String lowerFilename = filename.toLowerCase(); return ALLOWED_EXTENSIONS.stream() .anyMatch(lowerFilename::endsWith); } }