Att generera en PDF417‑streckkod kräver fyra rader Python. Att läsa tillbaka en sådan från ett foto på telefonen, en 200 DPI‑skanning eller ett boardingkort som har tillbringat en dag i någons ficka är där det verkliga arbetet börjar, och det är där de flesta PDF417‑integrationer faktiskt misslyckas. I den här artikeln kommer du att lära dig hur du läser PDF417‑streckkoder i Python när källbilden är bristfällig. Om du istället är intresserad av genereringssidan, täcker den tidigare genomgången om hur man genererar PDF417‑streckkoder med Python skapandet av grundläggande och anpassade PDF417‑symboler, inklusive rad‑ och kolumnkontroll, och Python‑streckkodsläsarguiden täcker allmän scanning över olika symboler. Det som följer här går på djupet och smalt på PDF417‑igenkänning.
Varje kodsnutt nedan kördes mot Aspose.BarCode for Python via .NET 26.7 på Linux med Python 3.12. Tiderna och läs-/missresultaten är mätta, inte uppskattade, och skriptet som skapade dem finns i slutet så att du kan köra om det på dina egna bilder.
Vad som faktiskt stör PDF417-igenkänning
PDF417 är en staplad symbologi: rader av kodord, där varje kodord byggs av fyra streck och fyra mellanslag som sträcker sig över 17 moduler. Den strukturen innehåller Reed‑Solomon‑felkorrigering, så ett slitet hörn eller en kaffefläck är vanligtvis överlevande. Vad som inte är överlevande är att förlora själva modulgittret.
Tre saker förstör rutnätet, i ungefärlig ordning efter hur ofta de dyker upp i produktion:
- Effektiv modulbredd som faller under två pixlar. Detta är det dominerande felet. Det sker genom nedskalning, genom kamerans avstånd och genom oskärpa, som sprider en moduls bläck över dess grannar. En streckkod som genereras med tre pixlar per modul och sedan oskärpas är i praktiken en streckkod med en pixel per modul.
- Perspektiv och rotation. En streckkod som fotograferas i en vinkel har rader som inte längre är parallella skanningslinjer. Detektorn hanterar detta, men det kräver ett detekteringspass som det snabbaste förinställningen hoppar över.
- Kontrastkollaps. Termiskt papper som har bleknat, en skärm fotograferad under bländning eller en skanning med ljusstyrkan låst. Mindre allvarligt än det ser ut, som siffrorna nedan visar.
Den praktiska konsekvensen är att igenkänningsinställningarna är en återhämtningsmekanism, inte en ersättning för fångstkvalitet. De köper tillbaka den mellersta delen av bildkvaliteten. De köper inte tillbaka den lägsta.
Ställ in Python PDF417-läsaren
Installera biblioteket från PyPI:
pip install aspose-barcode-for-python-via-net
Recognition‑API:t finns i aspose.barcode.barcoderecognition. Två klasser är relevanta för den här artikeln: BarCodeReader, som driver detektering och avkodning, och QualitySettings, som styr hur hårt läsaren försöker.
Läs en PDF417‑streckkod i Python
Den minsta livskraftiga läsningen är två argument och en loop:
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)

Läs en PDF417-streckkod i Python.
Utdata på en ren bild:
Code text: PASSENGER|KHAN/M|SEAT14C|LHE-DXB
Symbology: Pdf417
Reading quality: 100.0
Det andra argumentet är i praktiken inte valfritt. Utelämna det så återgår BarCodeReader till DecodeType.ALL_SUPPORTED_TYPES, vilket kör detektering för mer än sextio symboler mot varje kandidatregion i bilden. På en pipeline som bara hanterar PDF417 är det ren slöseri, och det öppnar dörren för ett falskt positivt resultat för en linjär symbolik inom PDF417‑radstrukturen. Ange typen.
Om ditt indata kommer som bytes från en uppladdning snarare än en fil på disk, skicka en ström och ange en tidsgräns så att en patologisk bild inte kan stoppa en arbetare:
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()]
Jämför PDF417 igenkänningskvalitetsinställningar i Python
QualitySettings levereras med fyra förinställningar som är värda att känna till. Att tilldela en till läsaren är en enda rad:
reader = rec.BarCodeReader("scan.png", rec.DecodeType.PDF417)
reader.quality_settings = rec.QualitySettings.high_quality
| Förinställning | Avsedd för | Kostnad |
|---|---|---|
high_performance | Rena, maskin-genererade bilder | Snabbast, hoppar över återhämtningspass |
normal_quality | Standard. Vanliga skanningar och export | Balanserad |
high_quality | Kamerabilder, försämrade skanningar | Måttlig |
max_quality | Omförsökspass på bilder som redan misslyckats | Långsammast med stor marginal |
För att ta reda på vad de beskrivningarna betyder i praktiken genererade jag en PDF417 med tre pixlar per modul, försämrade den på sex sätt med Pillow och körde varje förinställning mot varje variant. Median av tre körningar:
| Källa bild | high_performance | normal_quality | high_quality | max_quality |
|---|---|---|---|---|
| Ren | läst, 35 ms | läst, 50 ms | läst, 45 ms | läst, 106 ms |
| Roterad 12°, suddig | miss, 15 ms | läst, 74 ms | läst, 67 ms | läst, 157 ms |
| Gaussiskt brus (σ 40) | läst, 31 ms | läst, 49 ms | läst, 52 ms | läst, 123 ms |
| Halv upplösning | läst, 22 ms | läst, 37 ms | läst, 35 ms | läst, 86 ms |
| Låg kontrast | läst, 24 ms | läst, 38 ms | läst, 43 ms | läst, 112 ms |
| Stark oskärpa (σ 2.2) | miss, 5 ms | miss, 25 ms | miss, 85 ms | miss, 180 ms |
Fyra saker faller ut ur den här tabellen, och de är mer användbara än de enskilda siffrorna:
- Brus och låg kontrast är inte det problem som folk tror att de är. Reed-Solomon plus detektorn absorberade tungt Gaussiskt brus och en 82 % kontrastminskning på den snabbaste förinställningen. Sluta finjustera för dessa.
- Rotation plus suddighet är fallet som skiljer förinställningarna åt. Det är också den exakta profilen för en handhållen telefonupptagning, vilket är anledningen till att
high_performanceär fel standard för någon mobilkälla pipeline. max_qualitykostade tre gånger så lång tid somnormal_qualityoch läste inget extra. Den förtjänar sin plats som en andra‑försök‑väg, inte som standard.- När modulgittret är borta återställer ingen förinställning det. Den tunga suddighetsraden är ett misslyckande över hela linjen, och
max_qualityspenderade 180 ms på att bevisa det. Det är ett fångstproblem med en fångstlösning: fler pixlar, bättre fokus, störrex_dimensionvid genereringstid.
Justera QualitySettings för att läsa suddiga PDF417-streckkoder i Python
En förinställning är ett paket av enskilda egenskaper, och du kan börja med en förinställning och åsidosätta en. Det är här de verkliga vinsterna finns för ett känt, upprepningsbart fel.
Den roterade‑och‑suddiga bilden ovan är en bra demonstration. Under high_performance missar den. Aktivera dekonvolution ovanpå samma förinställning så läser den:
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)

Justera QualitySettings för att läsa suddiga PDF417-streckkoder i Python.
Mätt: miss i 12 ms utan överskrivning, läst i 54 ms med den. En egenskap vände resultatet, och resultatet kom fortfarande tillbaka snabbare än vad max_quality‑förinställningen skulle ha gjort.
Egenskaperna som är värda att känna till:
| Egenskap | Värden | När du bör använda den |
|---|---|---|
deconvolution | FAST, NORMAL, SLOW | Rörelseoskärpa och bilder med fel fokus |
barcode_quality | HIGH, NORMAL, LOW | Utskriftsdefekter, termisk blekning, faxartefakter |
x_dimension | AUTO, SMALL, NORMAL, LARGE, USE_MINIMAL_X_DIMENSION | Täta streckkoder, eller en fast känd modulstorlek |
minimal_x_dimension | float | Kombinera med USE_MINIMAL_X_DIMENSION för att ange ett minimum |
complex_background | AUTO, DISABLED, ENABLED | Streckkod tryckt över grafik eller ett mönstrat formulär |
inverse_image | AUTO, DISABLED, ENABLED | Vitt‑på‑svart streckkoder, skärmbilder |
allow_incorrect_barcodes | bool | Endast för diagnostik, aldrig i produktion |
Den sista förtjänar en varning. allow_incorrect_barcodes returnerar symboler som misslyckades med kontrollsummavalidering. Det är ett felsökningshjälpmedel för att besvara “hittade detektorn ens något här?” Att leverera det betyder att leverera avkodade strängar som är felaktiga snarare än frånvarande, vilket är strikt sämre än ett miss.
En nivåstrategi som fungerar bra i produktion: prova normal_quality först, och vid ett missförsök försök en gång till med high_quality plus deconvolution = SLOW. Du betalar den dyra vägen endast för de bilder som behöver det.
Validera PDF417‑avkodningsresultat i Python
En avkodad sträng är inte automatiskt en korrekt sträng. Tre fält på BarCodeResult hjälper:
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)]
Sätt ihop ett Macro PDF417 som är uppdelat över bilder
Macro PDF417 delar upp ett logiskt meddelande över flera symboler, vilket visas i fraktmanifest och flersidiga dokument. Segmentmetadata överlever rundresan, så återmontering är deterministisk:
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")

Sida 1.

Sida 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
Observera att
macro_pdf_417_file_idär ett heltal, inte en sträng, både på genererings- och igenkänningssidan. Samma objekt exponerar ocksåmacro_pdf_417_file_name,macro_pdf_417_sender,macro_pdf_417_addressee,macro_pdf_417_time_stampochmacro_pdf_417_checksumnär kodaren har fyllt i dem.
Benchmark PDF417-igenkänning på dina egna bilder
Förinställningsvalet bör vara en mätning, inte en gissning. Peka detta på en mapp med representativa fångster från din faktiska pipeline så kommer den att berätta vilken förinställning som förtjänar sin kostnad:
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
Kör det en gång mot femtio riktiga inspelningar och den förinställda debatten avslutas.
Praktiska riktlinjer
- Begränsa
DecodeTypetillPDF417om du inte verkligen förväntar dig blandade symbologier. AnvändMACRO_PDF417,COMPACT_PDF417ellerMICRO_PDF417när du känner till varianten. - Beskär innan du avkodar. Att skicka en hel A4‑skanning när streckkoden bara upptar 5 % av den slösar bort upptäcktstid och ger falska positiva resultat.
- Behåll mellanliggande filer förlustfritt. PNG eller TIFF. JPEG‑ringning vid låg kvalitet angriper exakt de streckkantskanter som avkodaren behöver.
- Dela upp dina omförsök istället för att alltid använda den långsammaste förinställningen.
- Fixa genereringen innan du finjusterar igenkänningen. Om du styr kodaren, kostar det inget att öka
x_dimensionoch löser fler missar än någon läsarinställning. Artikeln om PDF417‑generering (PDF417‑genereringsartikel) täcker dessa parametrar. - Ange
timeoutpå alla läsare som hanterar användargenererade bilder.
Få en gratis licens
Utvärderingsversionen vattenmärker avkodad text för symbologier förutom Code 39, vilket kan störa all rundresetestning du utför. En gratis tillfällig licens tar bort detta för utvärdering.
Gratis ytterligare resurser
- Alternativ för läskvalitet och förinställningar för streckkodsläsning
- Speciella fall för streckkodsläsning
- API-referens
- Gratis online-verktyg för streckkoder
Slutsats
Att läsa PDF417‑streckkoder i Python är en två‑radig operation på rena bilder och ett ingenjörsproblem på riktiga bilder. Mätningarna ovan pekar på en enkel strategi: namnge din DecodeType, standardvärdet normal_quality, försök igen en gång med high_quality och dekonvolution aktiverad, och validera varje resultat innan du agerar på det. Spara de dyra förinställningarna för återförsökspåret, och när en hel klass av bilder misslyckas med varje inställning, fixa inspelningen istället för läsaren. Frågor är välkomna på det gratis supportforumet.
FAQs
Varför läses samma PDF417-streckkod i en bild men misslyckas i en annan?
Upptäckten beror på hur många pixlar varje modul upptar efter inspelning. Oskärpa, nedskalning och JPEG‑komprimering minskar alla den effektiva modulbredden, och när en modul faller under ungefär två rena pixlar kan ingen förinställning återställa den.Vilken igenkänningsförinställning bör jag använda för PDF417?
Börja mednormal_quality, som är standard. Byt tillhigh_qualityför kamerainspelningar och skanningar, och reserveramax_qualityför omförsök eftersom den är flera gånger långsammare utan att läsa avsevärt mer.Gör det att begränsa DecodeType till PDF417 faktiskt läsningen snabbare?
Ja. Standardvärdet ärDecodeType.ALL_SUPPORTED_TYPES, vilket kör detektorn för varje stödd symbolik. Att explicit ange PDF417 tar bort det arbetet och eliminerar även risken för falskt positivt resultat från en annan symbolik.Kan Aspose.BarCode läsa ett Macro PDF417-meddelande som är uppdelat över flera bilder?
Ja. Läs varje segment medDecodeType.MACRO_PDF417och användmacro_pdf_417_file_id,macro_pdf_417_segment_idochmacro_pdf_417_segments_counti det utökade resultatet för att återmontera nyttolasten i rätt ordning.Hur vet jag om ett avkodat resultat är pålitligt?
Kontrollerareading_qualityochconfidencepåBarCodeResult, och användregion‑fyrkanten för att bekräfta att streckkoden hittades där du förväntade dig den i bilden.Kan den läsa PDF417 från ett foto av ett körkort eller boardingpass?
Den kan, förutsatt att inspelningen är i fokus och att streckkoden inte är avklippt. Beskär till streckkodsområdet innan läsning, och föredra PNG framför JPEG för mellanfiler.
