ZBar barcode and QR code scanner — decode from image files, bytes, or raw camera frames. QR, EAN, UPC, Code128, DataMatrix, PDF417 and more.
ppm install zbar
Requires libzbar-dev: sudo apt install libzbar-dev
Supported Symbologies
QR Code
EAN-13
EAN-8
UPC-A
UPC-E
Code 128
Code 39
Code 93
DataMatrix
PDF417
ISBN-10/13
I2 of 5
CodaBar
DataBar
SQ Code
EAN-2/5
Quick Start
uses zbar;
{ One-shot — scan file, get first result }
var data := ScanFileFirst('/tmp/qr.png');
Writeln(data); { e.g. 'https://example.com' }
{ Scan file — get all codes }
var result := ScanFile('/tmp/multi.png');
Writeln(IntToStr(result.Count) + ' codes found');
for sym in result.Symbols do
Writeln(sym.TypeName + ': ' + sym.Data);
Full API — With Position
uses zbar;
var scanner := NewScanner();
var result := ScanImageFile(scanner, '/tmp/invoice.jpg');
for sym in result.Symbols do
begin
Writeln('Type: ' + sym.TypeName);
Writeln('Data: ' + sym.Data);
Writeln('Quality: ' + IntToStr(sym.Quality));
var x, y, w, h: Integer;
GetBoundingBox(sym, x, y, w, h);
Writeln('At: (' + IntToStr(x) + ',' + IntToStr(y) +
') size ' + IntToStr(w) + 'x' + IntToStr(h));
end;
FreeScanner(scanner);
Only QR Codes (Faster)
var scanner := NewScanner();
DisableAll(scanner);
EnableSymbol(scanner, zbQRCode, True);
var result := ScanImageFile(scanner, '/tmp/qr.png');
Writeln(result.Symbols[0].Data);
FreeScanner(scanner);
Camera / Video Frames
{ Call this for every camera frame — raw grayscale bytes (width * height) }
{ Pair with opencv or portaudio to capture frames }
var scanner := NewScanner();
SetCacheEnabled(scanner, True); { suppress duplicate reads }
{ In your capture loop: }
var frame := { ... get grayscale bytes from camera ... }
var result := ScanGrayscale(scanner, frame, 640, 480);
if result.Count > 0 then
Writeln('Scanned: ' + result.Symbols[0].Data);
FreeScanner(scanner);
Filter by Type
var all := ScanFile('/tmp/mixed.png'); { has QR + EAN codes }
var qrOnly := FilterByType(all, zbQRCode);
for sym in qrOnly.Symbols do
Writeln(sym.Data);
API Reference
Scanner Lifecycle
| Function | Description |
| NewScanner | Create scanner with all symbologies enabled. |
| NewScannerEx(Config) | Create with custom TZBarConfig. |
| FreeScanner(Scanner) | Destroy scanner and free resources. |
| EnableSymbol(Scanner, Type, Enable) | Enable or disable a specific symbology. |
| DisableAll(Scanner) | Disable all symbologies (then re-enable selectively). |
| SetMinQuality(Scanner, N) | Reject reads below quality N (0–100). |
| SetCacheEnabled(Scanner, Enable) | Suppress duplicate reads in video mode. |
Scan
| Function | Description |
| ScanImageFile(Scanner, Path) | Scan from image file. Returns TZBarResult. |
| ScanImageBytes(Scanner, Data) | Scan from image byte string. |
| ScanGrayscale(Scanner, Pixels, W, H) | Raw grayscale bytes — fastest path for video. |
| ScanRGB(Scanner, Pixels, W, H) | Raw RGB bytes. |
Convenience (no handle)
| Function | Description |
| ScanFile(Path) | Scan file, return all results. |
| ScanFileFirst(Path) | Scan file, return first symbol data string. |
| ScanBytesFirst(Data) | Scan bytes, return first symbol data. |
Result Helpers
| Function | Description |
| FilterByType(Result, Type) | Keep only symbols of the given type. |
| GetBoundingBox(Symbol, X,Y,W,H) | Minimum enclosing rectangle of the symbol polygon. |
| GetCenter(Symbol, CX, CY) | Center point of the bounding polygon. |
| SymbolTypeName(Type) | Human-readable name for a TZBarSymbolType constant. |