Come l'OCR legge un PDF scansionato, e perché restituisce Markdown
Un PDF scansionato è un'immagine di testo. Questo OCR restituisce Markdown, non un PDF con strato nascosto: Auto usa il testo esistente, Force OCR rilegge tutto.

Un PDF scansionato memorizza le pagine come immagini raster: fotografie di testo, non caratteri selezionabili. L'OCR (optical character recognition) esamina quei pixel, deduce quali forme sono caratteri e produce testo reale. Su PDF123 questo avviene sia come strumento gratuito nel browser sia come POST /api/v1/misc/ocr-pdf; la risposta è Markdown, non un PDF riscritto.
La scansione resta un'immagine
L'OCR non pulisce, non nitidizza e non sostituisce la bitmap. Una scansione nitida che l'OCR legge male continua a sembrare nitida. L'immagine non è mai stata il collo di bottiglia della qualità: lo era il riconoscimento. Cambiare motore di riconoscimento sullo stesso lotto di scansioni può far variare l'accuratezza in modo netto, pur restando i pixel del tutto invariati.
L'OCR PDF classico scrive un secondo strato di testo, invisibile, allineato sotto l'immagine, così che selezione e ricerca cadano sulle parole giuste. È ciò che mostra il diagramma, ed è ancora il modo in cui funzionano molti strumenti desktop.
Cosa restituisce davvero questo endpoint
La pagina OCR chiama /api/v1/misc/ocr-pdf, che gira su un crate Rust a sé stante, pdf-inspector (compilato con la sua funzionalità ocr). Non passa l'intero PDF a un modello di riconoscimento. pdf-inspector classifica prima ogni pagina come dotata di testo nativo estraibile oppure come sola immagine. Le pagine con testo nativo mantengono quel testo così com'è e non toccano mai il modello di riconoscimento; le pagine di sola immagine passano invece per la pipeline di riconoscimento: PDFium (lo stesso motore di rendering open source che Chrome usa internamente) rasterizza la pagina, e ONNX Runtime esegue il modello PP-OCRv6 Small per leggerla. Entrambi i tipi di pagina vengono poi uniti in ordine in un unico documento Markdown, motivo per cui la risposta è text/markdown e il download termina in .md.
Questo contratto è nuovo con questa riscrittura. Il backend Java/Spring Boot che questo progetto usava in precedenza chiamava OCRmyPDF, l'approccio classico "immagine più strato di testo nascosto", e restituiva un PDF. La riscrittura in Rust ha sostituito completamente quel percorso con l'OCR selettivo di pdf-inspector, e con essa l'output è passato da PDF a Markdown. Il vecchio backend Java è stato da allora rimosso interamente dal repository; non è un interruttore che si possa riattivare.
Se ti serve un PDF ricercabile (immagine più strato di testo), questo è l'output sbagliato. Se ti serve testo che un agente o una pipeline possano leggere, Markdown è esattamente il punto.
Auto e Force OCR
Il modulo ha un campo ocrType:
- Normal (qualsiasi valore diverso da
force-ocr) corrisponde ad Auto: usa il testo esistente dove il file lo ha già e applica l'OCR alle pagine di sole immagini. Su un PDF nativo digitale pulito, Auto non carica il runtime OCR. - Force OCR (
ocrType=force-ocr) riesegue il riconoscimento su ogni pagina, comprese quelle che hanno già uno strato di testo. Sulle pagine realmente di sole immagini paghi tempo, non accuratezza in più; in cambio ottieni un passaggio che ignora uno strato esistente rotto o parziale.
Il valore predefinito del portale è Force OCR. Non esiste un controllo della lingua: i codici tessdata residui del vecchio percorso Java vengono ignorati.
La scelta tra Auto e Force avviene all'interno della richiesta stessa, e né il portale né la sonda di capacità dell'API la verificano in anticipo. GET /api/v1/settings/get-endpoints-status segnala sempre ocr-pdf come abilitato, senza verificare realmente se PDFium, ONNX Runtime o il modello PP-OCRv6 siano installati. Il controllo vero avviene solo nel momento in cui una richiesta attiva il riconoscimento: se manca uno di questi componenti, l'endpoint restituisce 503, invece di un Markdown degradato che ripiega silenziosamente sul solo testo nativo. Il modello PP-OCRv6 Small pesa circa 31 MB; a meno che non sia stato pre-caricato nella cache locale al momento del deploy, viene scaricato dalla rete la prima volta che una pagina ha davvero bisogno del riconoscimento. Una macchina offline senza modello pre-caricato molto probabilmente fallirà proprio lì, alla prima richiesta Force, invece di limitarsi a essere più lenta.
Il riconoscimento è probabilistico
I motori confrontano pattern di pixel con modelli di lettere e parole. Se la cavano bene con stampa pulita, ad alto contrasto e con font standard; peggio con:
- scansioni a bassa risoluzione o a basso contrasto (qualità fax rispetto a un originale a 300 DPI)
- scrittura a mano, font decorativi, impaginazioni insolite (tabelle a più colonne, testo ruotato, moduli densi)
- pagine inclinate che deformano le forme dei glifi quanto basta a confondere il confronto
Un fax sfocato non darà mai lo stesso OCR di una scansione pulita, con Auto o con Force. È un limite del modello stesso, non qualcosa che un parametro possa correggere.
Cosa l'OCR non fa
L'OCR ti dà del testo. Non ricostruisce paragrafi, titoli, tabelle o un documento Word reimpaginabile. Un layout modificabile è un problema di conversione che si somma all'errore di riconoscimento, non lo stesso lavoro che leggere una scansione.
OCR su un PDF gira lato server senza account. Il download è Markdown. Se uno strato di testo esistente sembra sbagliato, usa Force OCR perché Auto non si fidi di quello strato; per verificare se una determinata macchina ha davvero PDFium e il modello installati, lanciare una richiesta reale è più affidabile che leggere la sonda di capacità, dato che questa conferma solo che l'endpoint esiste, non che il suo runtime sia pronto. Per le chiavi di automazione e OpenAPI, vedi Developers.