zedbar
A pure Rust implementation of barcode scanning, based on the ZBar bar code reader C library.
This is a port of the ZBar library to Rust, providing barcode detection and decoding capabilities with a type-safe, idiomatic Rust API.
Features
- Multiple Barcode Formats: QR Code, EAN-13, EAN-8, EAN-2, EAN-5, UPC-A, UPC-E, ISBN-10, ISBN-13, Code 128, Code 93, Code 39, Codabar, Interleaved 2 of 5, DataBar (RSS), DataBar Expanded, SQCode
- Pure Rust: No C dependencies, fully memory-safe implementation
- Type-Safe Configuration: Compile-time validated configuration API
- Command-line Tool:
zedbarimgutility for scanning images from the command line - Position Tracking: Optional tracking of barcode positions in images
- Inverted Image Support: Can detect barcodes in inverted images
Installation
Cargo Features
By default, all symbologies are enabled. You can selectively enable only the ones you need to reduce compile time and binary size:
Symbology Features
qrcode- QR Code 2D barcodesqcode- SQ Code 2D barcodeean- EAN-8, EAN-13, EAN-2, EAN-5, UPC-A, UPC-E, ISBN-10, ISBN-13code128- Code 128code39- Code 39code93- Code 93codabar- Codabardatabar- GS1 DataBar (RSS) and DataBar Expandedi25- Interleaved 2 of 5
Optional Dependencies
Heavy dependencies (tied to features):
encoding_rs,reed-solomon,rand,rand_chacha- Required for QR code decoding (enabled withqrcodefeature)image- Image format loading (PNG, JPEG, etc.) - needed for tests and thezedbarimgbinaryclap- Command-line parsing (needed for thezedbarimgbinary)wasm-bindgen,js-sys,getrandom- JavaScript bindings (enabled with thewasmfeature, which is off by default and builds the npm package)
Note: 1D barcode decoders (EAN, Code39, Code128, etc.) have zero external dependencies!
The default feature enables all symbologies plus optional dependencies:
= ["qrcode", "sqcode", "ean", "code128", "code39", "code93", "codabar", "databar", "i25", "image", "clap"]
Minimal Library
For the absolute minimal build with zero external dependencies (1D barcodes only):
For QR codes only (with necessary dependencies):
Note: Disabling a feature at compile-time means that symbology will not be compiled into the binary at all, which is different from disabling it via runtime configuration.
Usage
Library
use ;
// Load an image and convert it for scanning
let img = open?;
let mut img = from_dynamic?;
// Create scanner and scan image
let mut scanner = new;
let symbols = scanner.scan;
// Process decoded symbols
for symbol in symbols
Image::from_dynamic (available with the image feature) composites any
transparency over white before converting to grayscale. Prefer it over
img.to_luma8(): a barcode drawn in black on a transparent background — the
usual shape of one rendered from SVG — loses its alpha in a direct conversion
and becomes black on black. If you already hold grayscale pixels, pass them
straight to Image::from_gray(data, width, height).
Locating a Symbol in the Image
Each symbol records the image-coordinate points where it was detected, which lets you draw a box around the decode or crop the source image.
for symbol in symbols
bounds() returns the AABB of points(), with width and height
reported as max - min of the recorded points (the extent between the
outermost points), not as a pixel count. Both return empty / None for
symbols that did not record any points.
Choosing Symbologies
DecoderConfig::new() starts empty — opt in to each symbology you need:
use *;
use ;
let config = new
.enable
.enable;
let mut scanner = with_config;
For exploratory use ("just scan whatever's there"), DecoderConfig::all()
or Scanner::new() enables every supported symbology in one call.
Advanced Configuration
use *;
use ;
let config = new
.enable
.enable
.set_length_limits // also enables Code39
.test_inverted // Try inverted image if no symbols found
.retry_undecoded_regions // Crop+upscale small QR codes automatically
.scan_density; // Scan every 2nd line (faster)
let mut scanner = with_config;
The per-symbology setters (set_length_limits, set_checksum,
set_uncertainty) auto-enable the symbology they target — if you've
already mentioned a symbology by name, it's on.
Small QR Codes in Large Images
When a QR code is too small relative to the image (e.g. a QR code on a scanned page), the scanner reports undecoded finder regions. You can handle these manually, or enable automatic retry:
use *;
use ;
// Option 1: Automatic retry. Each undecoded region is cropped, upscaled and
// rescanned, and any QR or SQ code recovered from it joins the results with
// its coordinates mapped back to the original image.
let config = new
.enable
.retry_undecoded_regions;
let mut scanner = with_config;
let result = scanner.scan;
// Option 2: Manual control via finder_regions(), which reports one entry per
// cluster of finder patterns that did not yield a symbol.
let mut scanner = new;
let result = scanner.scan;
for region in result.finder_regions
With automatic retry, the regions left in finder_regions() are the ones the
retry could not resolve.
Command-line Tool
zedbarimg scans one or more image files and prints what it finds, in the
manner of ZBar's zbarimg:
--quiet prints only the decoded data, --raw leaves it unconverted by any
charset, and --disable-all plus the --enable-* flags narrow the scan to
chosen symbologies. zedbarimg --help lists them all.
From a checkout of this repository, where the test images live:
# Install the binary from the working tree
# Or run it without installing. Use --release: a debug build carries
# overflow checks and no optimization, and scans far slower.
JavaScript
The same scanner is published to npm as zedbar,
compiled to WebAssembly, with its own zedbarimg command. See
npm/README.md.
Testing
Benchmarks
Comprehensive benchmarks comparing this library with rqrr, rxing, and the original C zbar library are available:
# Compare with rqrr (default)
# Compare with all libraries (requires optional dependencies)
See benches/README.md for detailed benchmark documentation and results.
Credits
Original ZBar Library
This project is based on the ZBar bar code reader library:
- Original C implementation: Copyright (C) 2007-2010 Jeff Brown spadix@users.sourceforge.net
- QR code decoder components: Copyright (C) 2008-2009 Timothy B. Terriberry (tterribe@xiph.org)
- SQCode decoder: Copyright (C) 2018 Javier Serrano Polo javier@jasp.net
- Current C library maintenance: Mauro Carvalho Chehab and contributors
The original ZBar library is licensed under LGPL 2.1 or later.
Rust Port
This Rust implementation preserves the algorithms and structure of the original C library while providing a safe, idiomatic Rust API.
Alternatives
If this library doesn't meet your needs, consider these alternatives:
Rust Libraries
- rqrr - Pure Rust QR code reader with a different algorithm. Fast and reliable for QR codes specifically, but only supports QR codes.
- bardecoder - Another Rust barcode decoder supporting various 1D formats.
- rxing - Rust port of ZXing (Zebra Crossing) library, supports many formats.
- quircs - Pure Rust port of the quirc QR code library.
C/C++ Libraries (via FFI)
- ZBar - The original C library this project is based on. Mature and well-tested.
- ZXing - Popular Java library with C++ port available.
- ZBar-lite - Lightweight fork of ZBar.
Choosing an Alternative
- For QR codes only: Consider
rqrr- it's fast, pure Rust, and has a simpler API. - For maximum format support: The original ZBar C library or ZXing are very mature.
- For pure Rust with broad format support: This library (
zedbar) orrxing. - For C bindings to ZBar: Use
zbar-rustwhich provides FFI bindings to the original C library.
License
LGPL 3.0 or later - See LICENSE for details.
This library is licensed under the GNU Lesser General Public License v3.0 or later, consistent with the original ZBar library's licensing.