feat(scan): whiten receipt backgrounds and embed OCR in PDFs
This commit is contained in:
@@ -6,15 +6,34 @@ import { runCommand } from "../commands.js"
|
||||
const agentRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..")
|
||||
const documentScript = path.join(agentRoot, "scripts/scan_document.py")
|
||||
|
||||
export const checkScanRuntime = async (config: AgentConfig, postprocess: boolean) => {
|
||||
const imports = postprocess && config.postprocessStrict ? "import PIL, cv2, numpy" : "import PIL"
|
||||
type ProcessingOptions = { ocr: boolean; ocrLanguage: string; backgroundCleanup: boolean }
|
||||
|
||||
export const checkScanRuntime = async (config: AgentConfig, postprocess: boolean, options: ProcessingOptions) => {
|
||||
const args = [documentScript, "--check-runtime", "--ocr-language", options.ocrLanguage]
|
||||
if (postprocess) args.push("--postprocess")
|
||||
if (config.postprocessStrict) args.push("--strict")
|
||||
if (options.backgroundCleanup) args.push("--background-cleanup")
|
||||
if (options.ocr) args.push("--ocr")
|
||||
try {
|
||||
const result = await runCommand(config.postprocessPython, ["-c", imports], { timeoutMs: 10_000 })
|
||||
const result = await runCommand(config.postprocessPython, args, { timeoutMs: 10_000 })
|
||||
if (result.code === 0) return
|
||||
} catch {
|
||||
throw new Error(result.stderr.trim())
|
||||
} catch (error) {
|
||||
// Report missing runtimes before the scanner consumes any paper.
|
||||
const detail = error instanceof Error ? error.message : String(error)
|
||||
throw new Error("Scan-Verarbeitung nicht verfügbar. Bitte den Agenten mit Python/Pillow, OpenCV und Tesseract samt OCR-Sprachpaketen installieren. " + detail)
|
||||
}
|
||||
throw new Error("Python/Pillow (bei strikter Nachbearbeitung zusätzlich OpenCV) fehlt. Bitte npm run setup:opencv ausführen oder python3-pil installieren.")
|
||||
}
|
||||
|
||||
export const processingCapabilities = async (config: AgentConfig) => {
|
||||
const available = async (options: ProcessingOptions) => {
|
||||
try { await checkScanRuntime(config, false, options); return true } catch { return false }
|
||||
}
|
||||
const [ocr, backgroundCleanup] = await Promise.all([
|
||||
available({ ocr: true, ocrLanguage: config.scanOcrLanguage, backgroundCleanup: false }),
|
||||
available({ ocr: false, ocrLanguage: config.scanOcrLanguage, backgroundCleanup: true }),
|
||||
])
|
||||
return { ocr, backgroundCleanup }
|
||||
}
|
||||
|
||||
export const createScanDocument = async (
|
||||
@@ -23,11 +42,14 @@ export const createScanDocument = async (
|
||||
outputPath: string,
|
||||
resolution: number,
|
||||
postprocess: boolean,
|
||||
profile: AgentConfig["postprocessProfile"]
|
||||
profile: AgentConfig["postprocessProfile"],
|
||||
options: ProcessingOptions
|
||||
): Promise<ScanResult> => {
|
||||
const args = [documentScript, "--output", outputPath, "--resolution", String(resolution), "--profile", profile]
|
||||
if (postprocess) args.push("--postprocess")
|
||||
if (config.postprocessStrict) args.push("--strict")
|
||||
if (options.backgroundCleanup) args.push("--background-cleanup")
|
||||
if (options.ocr) args.push("--ocr", "--ocr-language", options.ocrLanguage)
|
||||
args.push("--inputs", ...pages)
|
||||
|
||||
const result = await runCommand(config.postprocessPython, args, {
|
||||
|
||||
Reference in New Issue
Block a user