Generare un codice a barre PDF417 richiede quattro righe di Python. Leggerne uno da una foto scattata con il telefono, da una scansione a 200 DPI o da una carta d’imbarco che ha trascorso una giornata in tasca a qualcuno è dove inizia il vero lavoro, ed è dove la maggior parte delle integrazioni PDF417 fallisce realmente. In questo articolo imparerai come leggere i codici a barre PDF417 in Python quando l’immagine di origine è imperfetta. Se invece sei interessato alla parte di generazione, la guida precedente su come generare PDF417 barcodes using Python copre la creazione di simboli PDF417 di base e personalizzati, inclusi il controllo di righe e colonne, e la Python barcode reader guide tratta la scansione di uso generale su diverse simbologie. Quello che segue qui è un approfondimento specifico e dettagliato sul riconoscimento PDF417.
Ogni frammento qui sotto è stato eseguito con Aspose.BarCode for Python via .NET 26.7 su Linux con Python 3.12. I tempi e i risultati di lettura/mancata lettura sono misurati, non stimati, e lo script che li ha generati è alla fine così puoi rieseguirlo sulle tue immagini.
Cosa rompe effettivamente il riconoscimento PDF417
PDF417 è una simbologia impilata: righe di codeword, ciascuna codeword costruita da quattro barre e quattro spazi che coprono 17 moduli. Questa struttura incorpora la correzione di errori Reed‑Solomon, quindi un angolo strappato o una macchia di caffè di solito è sopravvivibile. Ciò che non è sopravvivibile è perdere la griglia dei moduli stessa.
Tre cose distruggono la griglia, in ordine approssimativo di frequenza con cui compaiono in produzione:
- Larghezza efficace del modulo inferiore a due pixel. Questo è il fallimento dominante. Si verifica tramite riduzione, distanza della fotocamera e sfocatura, che diffonde l’inchiostro di un modulo sui suoi vicini. Un codice a barre generato a tre pixel per modulo e poi sfocato è funzionalmente un codice a barre a un pixel per modulo.
- Prospettiva e rotazione. Un codice a barre fotografato da un angolo ha righe che non sono più linee di scansione parallele. Il rilevatore gestisce questo, ma richiede un passaggio di rilevamento che il preset più veloce salta.
- Collasso del contrasto. Carta termica sbiadita, uno schermo fotografato sotto abbagliamento o una scansione con la luminosità fissata. Meno fatale di quanto sembri, come mostrano i numeri sotto.
La conseguenza pratica è che le impostazioni di riconoscimento sono un meccanismo di recupero, non un sostituto della qualità di acquisizione. Esse ti restituiscono la fascia intermedia della qualità dell’immagine. Non restituiscono la fascia inferiore.
Configura il lettore PDF417 Python
Installa la libreria da PyPI:
pip install aspose-barcode-for-python-via-net
L’API di riconoscimento si trova in aspose.barcode.barcoderecognition. Due classi sono importanti per questo articolo: BarCodeReader, che gestisce il rilevamento e la decodifica, e QualitySettings, che controlla quanto intensamente il lettore tenta.
Leggi un codice a barre PDF417 in Python
La lettura minima fattibile richiede due argomenti e un ciclo:
from aspose.barcode import barcoderecognition as rec
reader = rec.BarCodeReader("clean.png", rec.DecodeType.PDF417)
for result in reader.read_bar_codes():
print("Code text:", result.code_text)
print("Symbology:", result.code_type_name)
print("Reading quality:", result.reading_quality)

Leggi un codice a barre PDF417 in Python.
Output su un’immagine pulita:
Code text: PASSENGER|KHAN/M|SEAT14C|LHE-DXB
Symbology: Pdf417
Reading quality: 100.0
Il secondo argomento non è opzionale in pratica. Se lo si omette, BarCodeReader ricade in DecodeType.ALL_SUPPORTED_TYPES, che esegue il rilevamento di più di sessanta simbologie su ogni regione candidata nell’immagine. Su una pipeline esclusivamente PDF417, ciò è puro spreco e apre la porta a un falso positivo di simbologia lineare all’interno della struttura di riga PDF417. Specifica il tipo.
Se il tuo input arriva come byte da un upload anziché come file su disco, passa uno stream e imposta un timeout in modo che un’immagine patologica non possa bloccare un worker:
import io
from aspose.barcode import barcoderecognition as rec
def decode_pdf417(image_bytes, timeout_ms=2000):
reader = rec.BarCodeReader(io.BytesIO(image_bytes), rec.DecodeType.PDF417)
reader.timeout = timeout_ms
return [r.code_text for r in reader.read_bar_codes()]
Confronta le impostazioni di qualità di riconoscimento PDF417 in Python
QualitySettings offre quattro preset da conoscere. Assegnarne uno al lettore è una singola riga:
reader = rec.BarCodeReader("scan.png", rec.DecodeType.PDF417)
reader.quality_settings = rec.QualitySettings.high_quality
| Preset | Destinato a | Costo |
|---|---|---|
high_performance | Immagini pulite generate dalla macchina | Il più veloce, salta i passaggi di recupero |
normal_quality | Predefinito. Scansioni ed esportazioni regolari | Bilanciato |
high_quality | Acquisizioni con fotocamera, scansioni degradate | Moderato |
max_quality | Passaggio di ritentativo su immagini già fallite | Il più lento di gran lunga |
Per scoprire cosa significano in pratica quelle descrizioni, ho generato un PDF417 a tre pixel per modulo, l’ho degradato in sei modi con Pillow e ho eseguito ogni preset su ogni variante. Mediana di tre esecuzioni:
| Immagine di origine | high_performance | normal_quality | high_quality | max_quality |
|---|---|---|---|---|
| Pulita | letto, 35 ms | letto, 50 ms | letto, 45 ms | letto, 106 ms |
| Ruotata 12°, sfocata | mancato, 15 ms | letto, 74 ms | letto, 67 ms | letto, 157 ms |
| Rumore gaussiano (σ 40) | letto, 31 ms | letto, 49 ms | letto, 52 ms | letto, 123 ms |
| Mezza risoluzione | letto, 22 ms | letto, 37 ms | letto, 35 ms | letto, 86 ms |
| Basso contrasto | letto, 24 ms | letto, 38 ms | letto, 43 ms | letto, 112 ms |
| Sfocatura forte (σ 2.2) | mancato, 5 ms | mancato, 25 ms | mancato, 85 ms | mancato, 180 ms |
Quattro cose emergono da questa tabella e sono più utili dei singoli numeri:
- Il rumore e il basso contrasto non sono il problema che la gente pensa siano. Reed‑Solomon più il rilevatore hanno assorbito un forte rumore gaussiano e una riduzione del contrasto dell'82 % nella preset più veloce. Smetti di ottimizzare per questi.
- Rotazione più sfocatura è il caso che separa le preset. È anche il profilo esatto di una cattura con telefono portatile, motivo per cui
high_performanceè l’impostazione predefinita sbagliata per qualsiasi pipeline di origine mobile. max_qualitycosta tre volte il tempo dinormal_qualitye non legge nulla di extra. Si guadagna il suo posto come percorso di secondo tentativo, non come predefinito.- Una volta che la griglia del modulo è sparita, nessuna preset la recupera. La riga con forte sfocatura è un errore in tutti i casi, e
max_qualityha impiegato 180 ms a dimostrarlo. È un problema di cattura con una correzione di cattura: più pixel, migliore messa a fuoco,x_dimensionpiù grande al momento della generazione.
Regola QualitySettings per leggere i codici a barre PDF417 sfocati in Python
Un preset è un insieme di proprietà individuali e puoi partire da un preset e sovrascriverne una. È qui che si trovano i reali vantaggi per un difetto noto e ripetibile.
L’immagine ruotata e sfocata sopra è una buona dimostrazione. Sotto high_performance non la rileva. Abilita la deconvoluzione sopra lo stesso preset e leggerà:
from aspose.barcode import barcoderecognition as rec
reader = rec.BarCodeReader("rotated.png", rec.DecodeType.PDF417)
quality = rec.QualitySettings.high_performance
quality.deconvolution = rec.DeconvolutionMode.NORMAL
reader.quality_settings = quality
for result in reader.read_bar_codes():
print(result.code_text)

Regola QualitySettings per leggere i codici a barre PDF417 sfocati in Python.
Misurato: mancato in 12 ms senza l’override, letto in 54 ms con esso. Una proprietà ha invertito l’esito e il risultato è tornato comunque più veloce rispetto al preset max_quality.
Le proprietà da conoscere:
| Proprietà | Valori | Quando usarla |
|---|---|---|
deconvolution | FAST, NORMAL, SLOW | Sfocatura da movimento e catture fuori fuoco |
barcode_quality | HIGH, NORMAL, LOW | Difetti di stampa, sbiadimento termico, artefatti fax |
x_dimension | AUTO, SMALL, NORMAL, LARGE, USE_MINIMAL_X_DIMENSION | Codici a barre densi, o una dimensione di modulo fissa conosciuta |
minimal_x_dimension | float | Usare insieme a USE_MINIMAL_X_DIMENSION per impostare un valore minimo |
complex_background | AUTO, DISABLED, ENABLED | Codice a barre stampato su un’opera d’arte o su un modulo a motivo |
inverse_image | AUTO, DISABLED, ENABLED | Codici a barre bianco su nero, catture schermo |
allow_incorrect_barcodes | bool | Solo per diagnostica, mai in produzione |
Quest’ultimo merita un avviso. allow_incorrect_barcodes restituisce simboli che non hanno superato la convalida del checksum. È uno strumento di debug per rispondere a “il rilevatore ha effettivamente trovato qualcosa qui?” Distribuirlo significa distribuire stringhe decodificate errate anziché assenti, il che è decisamente peggiore di una mancanza.
Una strategia a livelli che funziona bene in produzione: prova normal_quality per primo, e in caso di mancato risultato riprova una volta con high_quality più deconvolution = SLOW. Paghi il percorso costoso solo per le immagini che ne hanno bisogno.
Convalida i risultati della decodifica PDF417 in Python
Una stringa decodificata non è automaticamente una stringa corretta. Tre campi su BarCodeResult aiutano:
for result in reader.read_bar_codes():
print("Text:", result.code_text)
print("Reading quality:", result.reading_quality)
print("Confidence:", result.confidence)
print("Region:", [(p.x, p.y) for p in result.region.points])
Text: PASSENGER|KHAN/M|SEAT14C|LHE-DXB
Reading quality: 100.0
Confidence: 100
Region: [(7, 6), (261, 7), (261, 276), (7, 277)]
Ricomporre un Macro PDF417 diviso tra immagini
Macro PDF417 suddivide un messaggio logico in più simboli, che appare nei manifesti di spedizione e nei documenti multipagina. I metadati del segmento sopravvivono al viaggio di andata e ritorno, quindi il riassemblaggio è deterministico:
from aspose.barcode import barcoderecognition as rec
segments = {}
total = None
for path in ["page1.png", "page2.png"]:
reader = rec.BarCodeReader(path, rec.DecodeType.MACRO_PDF417)
for result in reader.read_bar_codes():
meta = result.extended.pdf417
segments[meta.macro_pdf_417_segment_id] = result.code_text
total = meta.macro_pdf_417_segments_count
print(f"{path}: segment {meta.macro_pdf_417_segment_id + 1} of {total}, "
f"file id {meta.macro_pdf_417_file_id}")
if total and len(segments) == total:
payload = "".join(segments[i] for i in sorted(segments))
print("Reassembled:", payload)
else:
print("Incomplete: missing segments")

Pagina 1.

Pagina 2.
Output:
Data\pdf417\page1.png: segment 1 of 2, file id 42
Data\pdf417\page2.png: segment 2 of 2, file id 42
Reassembled: SEGMENT-A-DATASEGMENT-B-DATA
Nota che
macro_pdf_417_file_idè un intero, non una stringa, sia sul lato di generazione che di riconoscimento. Lo stesso oggetto espone anchemacro_pdf_417_file_name,macro_pdf_417_sender,macro_pdf_417_addressee,macro_pdf_417_time_stampemacro_pdf_417_checksumquando l’encoder li ha popolati.
Benchmark del riconoscimento PDF417 sulle tue immagini
La scelta del preset dovrebbe essere una misurazione, non un’ipotesi. Puntalo a una cartella di catture rappresentative dal tuo pipeline reale e ti dirà quale preset giustifica il suo costo:
import time, statistics, pathlib
from aspose.barcode import barcoderecognition as rec
PRESETS = ["high_performance", "normal_quality", "high_quality", "max_quality"]
def probe(path, preset, reps=3):
times, found = [], False
for _ in range(reps):
reader = rec.BarCodeReader(str(path), rec.DecodeType.PDF417)
reader.quality_settings = getattr(rec.QualitySettings, preset)
start = time.perf_counter()
results = list(reader.read_bar_codes())
times.append((time.perf_counter() - start) * 1000)
found = found or bool(results)
return found, statistics.median(times)
for image in sorted(pathlib.Path("samples").glob("*.png")):
row = []
for preset in PRESETS:
found, ms = probe(image, preset)
row.append(f"{preset}: {'read' if found else 'miss'} {ms:.0f}ms")
print(f"{image.name:28} " + " | ".join(row))
clean.png high_performance: read 32ms | normal_quality: read 48ms | high_quality: read 51ms | max_quality: read 130ms
faded_thermal.png high_performance: read 26ms | normal_quality: read 43ms | high_quality: read 46ms | max_quality: read 144ms
half_resolution.png high_performance: read 27ms | normal_quality: read 41ms | high_quality: read 41ms | max_quality: read 89ms
heavy_blur.png high_performance: miss 7ms | normal_quality: miss 24ms | high_quality: miss 69ms | max_quality: miss 180ms
noisy_scan.png high_performance: read 26ms | normal_quality: read 42ms | high_quality: read 47ms | max_quality: read 116ms
Page1.png high_performance: read 21ms | normal_quality: read 34ms | high_quality: read 38ms | max_quality: read 90ms
Page2.png high_performance: read 21ms | normal_quality: read 33ms | high_quality: read 38ms | max_quality: read 89ms
rotated.png high_performance: miss 16ms | normal_quality: read 43ms | high_quality: read 57ms | max_quality: read 147ms
Eseguilo una volta contro cinquanta catture reali e il dibattito predefinito termina.
Linee guida pratiche
- Limita
DecodeTypeaPDF417a meno che non ti aspetti realmente simbologie miste. UsaMACRO_PDF417,COMPACT_PDF417oMICRO_PDF417quando conosci la variante. - Ritaglia prima di decodificare. Inviare una scansione A4 completa quando il codice a barre occupa solo il 5 % spreca tempo di rilevamento e aggiunge falsi positivi.
- Mantieni i file intermedi senza perdita. PNG o TIFF. JPEG con artefatti a impostazioni di bassa qualità colpisce proprio i bordi del codice di cui il decoder ha bisogno.
- Scala i tuoi tentativi invece di usare il preset più lento per impostazione predefinita.
- Correggi la generazione prima di ottimizzare il riconoscimento. Se controlli l’encoder, aumentare
x_dimensionnon costa nulla e risolve più errori rispetto a qualsiasi impostazione del lettore. L’articolo sulla generazione di PDF417 copre questi parametri. - Imposta
timeoutsu qualsiasi lettore che elabora immagini fornite dall’utente.
Ottieni una licenza gratuita
La build di valutazione aggiunge filigrane al testo decodificato per le simbologie diverse da Code 39, il che interferirà con qualsiasi test di round‑trip che esegui. Una licenza temporanea gratuita rimuove questo per la valutazione.
Risorse aggiuntive gratuite
- Opzioni di Qualità di Lettura del Codice a Barre e Preset
- Casi Speciali di Lettura del Codice a Barre
- Riferimento API
- Strumenti Gratuiti per Codici a Barre Online
Conclusione
La lettura dei codici a barre PDF417 in Python è un’operazione a due righe su immagini pulite e un problema ingegneristico su quelle reali. Le misurazioni sopra indicano una postura semplice: specifica il tuo DecodeType, usa normal_quality come predefinito, riprova una volta con high_quality e deconvolution abilitata, e valida ogni risultato prima di agire su di esso. Conserva le impostazioni costose per il percorso di retry e, quando un’intera classe di immagini fallisce in ogni impostazione, correggi la cattura anziché il lettore. Le domande sono benvenute sul forum di supporto gratuito.
Domande frequenti
Perché lo stesso codice a barre PDF417 viene letto in un’immagine e fallisce in un’altra?
Il riconoscimento dipende da quanti pixel occupa ogni modulo dopo l’acquisizione. Sfocatura, ridimensionamento e compressione JPEG riducono tutti la larghezza effettiva del modulo e, una volta che un modulo scende al di sotto di circa due pixel puliti, nessun preset può recuperarlo.Quale preset di riconoscimento dovrei usare per PDF417?
Inizia connormal_quality, che è quello predefinito. Passa ahigh_qualityper acquisizioni con fotocamera e scansioni, e riservamax_qualityper i tentativi di ripetizione perché è diverse volte più lento senza leggere molto di più.Limitare DecodeType a PDF417 rende effettivamente la lettura più veloce?
Sì. Il valore predefinito èDecodeType.ALL_SUPPORTED_TYPES, che esegue il rilevatore per ogni simbologia supportata. Specificare esplicitamente PDF417 elimina quel lavoro e rimuove anche la possibilità di un falso positivo da un’altra simbologia.Aspose.BarCode può leggere un messaggio Macro PDF417 suddiviso in più immagini?
Sì. Leggi ogni segmento conDecodeType.MACRO_PDF417e utilizzamacro_pdf_417_file_id,macro_pdf_417_segment_idemacro_pdf_417_segments_countnel risultato esteso per ricomporre il payload in ordine.Come posso sapere se un risultato decodificato è affidabile?
Controllareading_qualityeconfidencesulBarCodeResulte utilizza il quadrilateroregionper confermare che il codice a barre sia stato trovato dove ti aspettavi nell’immagine.Può leggere PDF417 da una foto di una patente di guida o di una carta d’imbarco?
Sì, a condizione che l’acquisizione sia a fuoco e il codice a barre non sia tagliato. Ritaglia l’area del codice a barre prima della lettura e preferisci PNG rispetto a JPEG per i file intermedi.
