Créer un code‑barres PDF417 ne nécessite que quatre lignes de Python. Lire ce code à partir d’une photo prise avec un téléphone, d’un scan à 200 DPI ou d’une carte d’embarquement qui a passé une journée dans la poche de quelqu’un est le moment où le vrai travail commence, et c’est là que la plupart des intégrations PDF417 échouent réellement. Dans cet article, vous apprendrez comment lire les codes‑barres PDF417 en Python lorsque l’image source est imparfaite. Si vous cherchez plutôt la partie génération, le guide précédent sur la façon de générer des codes‑barres PDF417 avec Python couvre la création de symboles PDF417 de base et personnalisés, y compris le contrôle des lignes et des colonnes, et le guide du lecteur de codes‑barres Python couvre la numérisation à usage général à travers les différentes symbologies. Ce qui suit ici se concentre de manière étroite et approfondie sur la reconnaissance PDF417.
Chaque extrait ci‑dessous a été exécuté avec Aspose.BarCode for Python via .NET 26.7 sous Linux avec Python 3.12. Les temps d’exécution et les résultats de lecture/échec sont mesurés, pas estimés, et le script qui les a générés se trouve à la fin afin que vous puissiez le réexécuter sur vos propres images.
Ce qui perturbe réellement la reconnaissance PDF417
PDF417 est une symbologie empilée : des lignes de mots‑code, chaque mot‑code étant construit à partir de quatre barres et quatre espaces s’étendant sur 17 modules. Cette structure intègre la correction d’erreurs Reed‑Solomon, de sorte qu’un coin déchiré ou une tache de café est généralement survivable. Ce qui n’est pas survivable, c’est la perte de la grille de modules elle‑même.
Trois choses détruisent la grille, dans l’ordre approximatif de leur fréquence d’apparition en production :
- Largeur de module efficace inférieure à deux pixels. C’est la défaillance dominante. Elle se produit lors de la réduction d’échelle, à cause de la distance de la caméra, ou à cause du flou, qui étale l’encre d’un module sur ses voisins. Un code‑barres généré à trois pixels par module puis flouté équivaut fonctionnellement à un code‑barres à un pixel par module.
- Perspective et rotation. Un code‑barres photographié sous un angle a des rangées qui ne sont plus parallèles aux lignes de balayage. Le détecteur gère cela, mais cela nécessite un passage de détection que le préréglage le plus rapide ignore.
- Effondrement du contraste. Papier thermique qui a pâli, écran photographié sous l’éblouissement, ou numérisation avec la luminosité figée. Moins fatal qu’il n’y paraît, comme le montrent les chiffres ci‑dessous.
La conséquence pratique est que les paramètres de reconnaissance sont un mécanisme de récupération, et non un substitut à la qualité de capture. Ils vous permettent de récupérer la bande moyenne de la qualité d’image. Ils ne permettent pas de récupérer la partie inférieure.
Configurer le lecteur PDF417 en Python
Installez la bibliothèque depuis PyPI :
pip install aspose-barcode-for-python-via-net
L’API de reconnaissance se trouve dans aspose.barcode.barcoderecognition. Deux classes sont importantes pour cet article : BarCodeReader, qui gère la détection et le décodage, et QualitySettings, qui contrôle l’intensité avec laquelle le lecteur travaille.
Lire un code-barres PDF417 en Python
La lecture minimale viable nécessite deux arguments et une boucle :
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)

Lire un code-barres PDF417 en Python.
Résultat sur une image propre :
Code text: PASSENGER|KHAN/M|SEAT14C|LHE-DXB
Symbology: Pdf417
Reading quality: 100.0
Le deuxième argument n’est pas optionnel en pratique. Omettez‑le et BarCodeReader revient à DecodeType.ALL_SUPPORTED_TYPES, ce qui lance la détection de plus de soixante symbologies sur chaque région candidate de l’image. Sur un pipeline uniquement PDF417, c’est du pur gaspillage, et cela ouvre la porte à un faux positif de symbologie linéaire à l’intérieur de la structure de ligne PDF417. Nommez le type.
Si votre entrée arrive sous forme d’octets provenant d’un téléchargement plutôt que d’un fichier sur le disque, transmettez un flux et définissez un délai d’attente afin qu’une image pathologique ne puisse pas bloquer un travailleur :
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()]
Comparer les paramètres de qualité de reconnaissance PDF417 en Python
QualitySettings propose quatre préréglages à connaître. L’assigner au lecteur se fait en une seule ligne :
reader = rec.BarCodeReader("scan.png", rec.DecodeType.PDF417)
reader.quality_settings = rec.QualitySettings.high_quality
| Preset | Destiné à | Coût |
|---|---|---|
high_performance | Images propres, générées par machine | Le plus rapide, saute les passes de récupération |
normal_quality | Par défaut. Scans et exportations réguliers | Équilibré |
high_quality | Captures d’appareil photo, scans dégradés | Modéré |
max_quality | Passe de réessai sur les images déjà échouées | Le plus lent de loin |
Pour savoir ce que ces descriptions signifient en pratique, j’ai généré un PDF417 à trois pixels par module, l’ai dégradé de six manières avec Pillow, et j’ai exécuté chaque préréglage contre chaque variante. Médiane de trois exécutions :
| Image source | high_performance | normal_quality | high_quality | max_quality |
|---|---|---|---|---|
| Propre | lu, 35 ms | lu, 50 ms | lu, 45 ms | lu, 106 ms |
| Pivoté de 12°, flou | manqué, 15 ms | lu, 74 ms | lu, 67 ms | lu, 157 ms |
| Bruit gaussien (σ 40) | lu, 31 ms | lu, 49 ms | lu, 52 ms | lu, 123 ms |
| Demi résolution | lu, 22 ms | lu, 37 ms | lu, 35 ms | lu, 86 ms |
| Faible contraste | lu, 24 ms | lu, 38 ms | lu, 43 ms | lu, 112 ms |
| Flou important (σ 2.2) | manqué, 5 ms | manqué, 25 ms | manqué, 85 ms | manqué, 180 ms |
Quatre choses ressortent de ce tableau, et elles sont plus utiles que les chiffres individuels :
- Le bruit et le faible contraste ne sont pas le problème que les gens croient. Reed-Solomon plus le détecteur ont absorbé un bruit gaussien important et une réduction de contraste de 82 % sur le préréglage le plus rapide. Arrêtez d’ajuster pour ceux‑ci.
- La rotation plus le flou est le cas qui sépare les préréglages. C’est également le profil exact d’une capture à partir d’un téléphone portable, ce qui explique pourquoi
high_performanceest le mauvais défaut pour tout pipeline provenant d’un mobile. max_qualitycoûte trois fois le temps denormal_qualityet ne lit rien de supplémentaire. Il mérite sa place comme voie de seconde tentative, pas comme défaut.- Une fois la grille du module disparue, aucun préréglage ne la récupère. La ligne de flou important est un échec généralisé, et
max_qualitya passé 180 ms à le prouver. C’est un problème de capture avec une solution de capture : plus de pixels, une meilleure mise au point, unx_dimensionplus grand lors de la génération.
Ajuster QualitySettings pour lire les codes-barres PDF417 flous en Python
Un préréglage est un ensemble de propriétés individuelles, et vous pouvez partir d’un préréglage et en remplacer une. C’est là que résident les véritables gains pour un défaut connu et reproductible.
L’image tournée et floue ci‑dessus est une bonne démonstration. Sous high_performance elle manque. Activez la déconvolution sur le même préréglage et cela donne :
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)

Ajustez QualitySettings pour lire les codes-barres PDF417 flous en Python.
Mesuré : échec en 12 ms sans le remplacement, lecture en 54 ms avec. Une propriété a inversé le résultat, et le résultat est toujours revenu plus rapidement que le préréglage max_quality ne l’aurait fait.
Les propriétés à connaître :
| Property | Values | Quand l’utiliser |
|---|---|---|
deconvolution | FAST, NORMAL, SLOW | Flou de mouvement et captures hors mise au point |
barcode_quality | HIGH, NORMAL, LOW | Défauts d’impression, décoloration thermique, artefacts de fax |
x_dimension | AUTO, SMALL, NORMAL, LARGE, USE_MINIMAL_X_DIMENSION | Codes-barres denses, ou une taille de module fixe connue |
minimal_x_dimension | float | À associer avec USE_MINIMAL_X_DIMENSION pour définir une valeur minimale |
complex_background | AUTO, DISABLED, ENABLED | Code-barres imprimé sur une illustration ou un formulaire à motifs |
inverse_image | AUTO, DISABLED, ENABLED | Codes-barres blanc sur noir, captures d’écran |
allow_incorrect_barcodes | bool | Diagnostics uniquement, jamais en production |
Ce dernier mérite un avertissement. allow_incorrect_barcodes renvoie des symboles qui ont échoué la validation du contrôle de somme. C’est une aide au débogage pour répondre à « did the detector even find something here? ». Le déployer signifie expédier des chaînes décodées qui sont incorrectes plutôt qu’absentes, ce qui est strictement pire qu’un simple manque.
Une stratégie de hiérarchisation qui fonctionne bien en production : essayez d’abord normal_quality, puis, en cas d’échec, réessayez une fois avec high_quality plus deconvolution = SLOW. Vous ne payez le chemin coûteux que pour les images qui en ont besoin.
Valider les résultats du décodage PDF417 en Python
Une chaîne décodée n’est pas automatiquement une chaîne correcte. Trois champs sur BarCodeResult aident :
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)]
Réassembler un Macro PDF417 réparti sur plusieurs images
Macro PDF417 divise un message logique en plusieurs symboles, ce qui apparaît dans les manifestes d’expédition et les documents multi‑pages. Les métadonnées du segment survivent au voyage aller‑retour, de sorte que le réassemblage est déterministe :
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")

Page 1.

Page 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
Notez que
macro_pdf_417_file_idest un entier, pas une chaîne, à la fois du côté de la génération et de la reconnaissance. Le même objet expose égalementmacro_pdf_417_file_name,macro_pdf_417_sender,macro_pdf_417_addressee,macro_pdf_417_time_stampetmacro_pdf_417_checksumlorsque l’encodeur les a remplis.
Évaluer la reconnaissance PDF417 sur vos propres images
Le choix du préréglage doit être une mesure, pas une supposition. Pointez-le vers un dossier contenant des captures représentatives de votre pipeline réel et il vous indiquera quel préréglage justifie son coût :
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
Exécutez-le une fois contre cinquante captures réelles et le débat prédéfini se termine.
Directives pratiques
- Restreignez
DecodeTypeàPDF417à moins que vous ne prévoyiez réellement des symbologies mixtes. UtilisezMACRO_PDF417,COMPACT_PDF417ouMICRO_PDF417lorsque vous connaissez la variante. - Recadrez avant de décoder. Fournir un scan complet A4 alors que le code‑barres n’en occupe que 5 % gaspille le temps de détection et augmente les faux positifs.
- Conservez les fichiers intermédiaires sans perte. PNG ou TIFF. Le JPEG avec des réglages de faible qualité crée des artefacts qui affectent précisément les bords du code que le décodeur doit lire.
- Hiérarchisez vos nouvelles tentatives plutôt que de vous rabattre sur le préréglage le plus lent.
- Corrigez la génération avant d’ajuster la reconnaissance. Si vous contrôlez l’encodeur, augmenter
x_dimensionne coûte rien et résout plus d’échecs que n’importe quel réglage du lecteur. L’article sur la génération PDF417 couvre ces paramètres. - Définissez
timeoutsur tout lecteur qui traite des images fournies par l’utilisateur.
Obtenez une licence gratuite
La version d’évaluation ajoute un filigrane au texte décodé pour les symbologies autres que Code 39, ce qui interférera avec tout test de bout en bout que vous effectuez. Une licence temporaire gratuite supprime cela pour l’évaluation.
Ressources supplémentaires gratuites
- Options de qualité de lecture de code-barres et préréglages
- Cas spéciaux de lecture de code-barres
- Référence API
- Outils de code-barres en ligne gratuits
Conclusion
Lire les codes‑barres PDF417 en Python est une opération en deux lignes sur des images propres et un problème d’ingénierie sur les images réelles. Les mesures ci‑dessus indiquent une posture simple : nommez votre DecodeType, utilisez normal_quality par défaut, réessayez une fois avec high_quality et la déconvolution activée, puis validez chaque résultat avant d’agir. Conservez les préréglages coûteux pour le chemin de réessai et, lorsqu’une classe entière d’images échoue à chaque réglage, corrigez la capture plutôt que le lecteur. Les questions sont les bienvenues sur le forum de support gratuit.
FAQs
Pourquoi le même code‑barres PDF417 est‑il lu dans une image et échoue dans une autre ?
La reconnaissance dépend du nombre de pixels que chaque module occupe après la capture. Le flou, la réduction d’échelle et la compression JPEG réduisent tous la largeur effective du module, et lorsqu’un module descend en dessous d’environ deux pixels nets, aucun préréglage ne pourra le récupérer.Quel préréglage de reconnaissance devrais‑je utiliser pour PDF417 ?
Commencez avecnormal_quality, qui est la valeur par défaut. Passez àhigh_qualitypour les captures et les scans avec appareil photo, et réservezmax_qualitypour les passes de réessai car il est plusieurs fois plus lent sans lire beaucoup plus.Restreindre DecodeType à PDF417 accélère‑t‑il réellement la lecture ?
Oui. La valeur par défaut estDecodeType.ALL_SUPPORTED_TYPES, qui exécute le détecteur pour chaque symbologie prise en charge. Spécifier explicitement PDF417 supprime ce travail et élimine également la possibilité d’un faux positif provenant d’une autre symbologie.Aspose.BarCode peut‑il lire un message Macro PDF417 réparti sur plusieurs images ?
Oui. Lisez chaque segment avecDecodeType.MACRO_PDF417et utilisezmacro_pdf_417_file_id,macro_pdf_417_segment_idetmacro_pdf_417_segments_countsur le résultat étendu pour réassembler la charge utile dans l’ordre.Comment savoir si un résultat décodé est fiable ?
Vérifiezreading_qualityetconfidencesur leBarCodeResult, et utilisez le quadrilatèreregionpour confirmer que le code‑barres a été trouvé à l’endroit attendu dans l’image.Peut‑il lire un PDF417 à partir d’une photo d’un permis de conduire ou d’une carte d’embarquement ?
Oui, à condition que la capture soit nette et que le code‑barres ne soit pas coupé. Recadrez la région du code‑barres avant la lecture, et privilégiez le PNG plutôt que le JPEG pour les fichiers intermédiaires.
