or run

tessl search
Log in

Version

Workspace
tessl
Visibility
Public
Created
Last updated

docs

index.md
tile.json

tessl/github-zxing-cpp--zxing-cpp

tessl install tessl/github-zxing-cpp--zxing-cpp@2.3.0

Open-source, multi-format linear/matrix barcode image processing library implemented in C++

reading.mddocs/reference/

Barcode Reading

The ZXing-C++ reading API provides functions to detect and decode barcodes from images. The library supports reading single or multiple barcodes from an image with extensive configuration options.

Core Reading Functions

namespace ZXing {
    /**
     * Read a single barcode from an image.
     * Stops after finding the first valid barcode.
     *
     * @param image  ImageView of the image data
     * @param options  Optional ReaderOptions for configuration (default: empty options)
     * @return Barcode result (check isValid() to see if barcode was found)
     */
    Barcode ReadBarcode(const ImageView& image, const ReaderOptions& options = {});

    /**
     * Read multiple barcodes from an image.
     * Searches for all barcodes up to maxNumberOfSymbols limit.
     *
     * @param image  ImageView of the image data
     * @param options  Optional ReaderOptions for configuration (default: empty options)
     * @return Vector of Barcode results (may be empty if no barcodes found)
     */
    Barcodes ReadBarcodes(const ImageView& image, const ReaderOptions& options = {});
}

Usage Examples

Read Single Barcode

#include "ZXing/ReadBarcode.h"

// Assuming you have image data loaded
uint8_t* imageData = ...; // Your image data
int width = ...;
int height = ...;

// Create ImageView (for grayscale image)
auto image = ZXing::ImageView(imageData, width, height, ZXing::ImageFormat::Lum);

// Read barcode with default options
auto barcode = ZXing::ReadBarcode(image);

if (barcode.isValid()) {
    std::cout << "Found: " << barcode.text() << "\n";
    std::cout << "Format: " << ZXing::ToString(barcode.format()) << "\n";
} else {
    std::cerr << "No barcode found\n";
}

Read Multiple Barcodes

#include "ZXing/ReadBarcode.h"

auto image = ZXing::ImageView(data, width, height, ZXing::ImageFormat::RGB);

// Configure to find up to 10 barcodes
auto options = ZXing::ReaderOptions()
    .setMaxNumberOfSymbols(10)
    .setFormats(ZXing::BarcodeFormat::Any);

auto barcodes = ZXing::ReadBarcodes(image, options);

std::cout << "Found " << barcodes.size() << " barcodes:\n";
for (const auto& bc : barcodes) {
    if (bc.isValid()) {
        std::cout << "  " << ZXing::ToString(bc.format())
                  << ": " << bc.text() << "\n";
    }
}

Read Specific Format

// Only look for QR codes
auto options = ZXing::ReaderOptions()
    .setFormats(ZXing::BarcodeFormat::QRCode);

auto barcode = ZXing::ReadBarcode(image, options);

Read Multiple Formats

// Look for QR codes, Data Matrix, or PDF417
auto formats = ZXing::BarcodeFormat::QRCode
             | ZXing::BarcodeFormat::DataMatrix
             | ZXing::BarcodeFormat::PDF417;

auto options = ZXing::ReaderOptions().setFormats(formats);
auto barcodes = ZXing::ReadBarcodes(image, options);

Read with Enhanced Detection

// Use more aggressive scanning strategies
auto options = ZXing::ReaderOptions()
    .setFormats(ZXing::BarcodeFormat::Any)
    .setTryHarder(true)       // Spend more time looking
    .setTryRotate(true)       // Try 90/180/270 degree rotations
    .setTryInvert(true)       // Try inverted colors
    .setTryDownscale(true);   // Try downscaled images

auto barcodes = ZXing::ReadBarcodes(image, options);

Read from Different Image Formats

// Grayscale image
auto imageLum = ZXing::ImageView(data, width, height, ZXing::ImageFormat::Lum);

// RGB image
auto imageRGB = ZXing::ImageView(data, width, height, ZXing::ImageFormat::RGB);

// RGBA image (with alpha channel)
auto imageRGBA = ZXing::ImageView(data, width, height, ZXing::ImageFormat::RGBA);

// BGR image (common in OpenCV)
auto imageBGR = ZXing::ImageView(data, width, height, ZXing::ImageFormat::BGR);

// All work the same way
auto barcode = ZXing::ReadBarcode(imageLum);

Read with Custom Stride

// If your image data has padding or custom layout
int rowStride = width * 3 + 16;  // 16 bytes padding per row
int pixStride = 3;                // 3 bytes per pixel (RGB)

auto image = ZXing::ImageView(data, width, height,
                              ZXing::ImageFormat::RGB,
                              rowStride, pixStride);

auto barcode = ZXing::ReadBarcode(image);

Read from Image Region

// Read from a specific region of interest
auto fullImage = ZXing::ImageView(data, width, height, ZXing::ImageFormat::Lum);

// Crop to region (left, top, width, height)
auto roi = fullImage.cropped(100, 100, 400, 300);

auto barcode = ZXing::ReadBarcode(roi);

Read with Error Reporting

auto options = ZXing::ReaderOptions()
    .setReturnErrors(true);  // Return barcodes even if they have errors

auto barcodes = ZXing::ReadBarcodes(image, options);

for (const auto& bc : barcodes) {
    if (bc.isValid()) {
        std::cout << "Valid: " << bc.text() << "\n";
    } else {
        std::cerr << "Error: " << bc.error().msg()
                  << " (type: " << static_cast<int>(bc.error().type()) << ")\n";
    }
}

Reading Strategies

Try Harder Mode

When tryHarder is enabled, the library spends more time analyzing the image to find difficult-to-detect barcodes:

auto options = ZXing::ReaderOptions().setTryHarder(true);

This is useful for:

  • Low-quality images
  • Small barcodes
  • Damaged or partially obscured barcodes
  • Barcodes with poor contrast

Rotation Detection

Enable rotation detection to find barcodes at any angle:

auto options = ZXing::ReaderOptions().setTryRotate(true);

The library will try 0°, 90°, 180°, and 270° orientations.

Inverted Barcode Detection

Some barcode formats support inverted colors (dark background, light barcode):

auto options = ZXing::ReaderOptions().setTryInvert(true);

Downscaling for Large Images

For very large images, downscaling can improve performance:

auto options = ZXing::ReaderOptions()
    .setTryDownscale(true)
    .setDownscaleThreshold(500)  // Downscale if min(width,height) > 500
    .setDownscaleFactor(3);       // Scale factor (2, 3, or 4)

Pure Barcode Mode

If you know the image contains only a single, perfectly aligned barcode (e.g., a generated image):

auto options = ZXing::ReaderOptions().setIsPure(true);

This enables fast-path processing with no rotation or perspective correction.

Binarization Strategies

The library converts grayscale images to binary (black/white) using different algorithms:

enum class Binarizer {
    LocalAverage,    // Average of neighboring pixels (default for matrix codes)
    GlobalHistogram, // Valley between peaks in histogram (default for linear codes)
    FixedThreshold,  // Fixed threshold at 127
    BoolCast         // Threshold at 0 (fastest, for already-binary images)
};

Usage:

auto options = ZXing::ReaderOptions()
    .setBinarizer(ZXing::Binarizer::GlobalHistogram);

Linear Barcode Options

Minimum Line Count

For linear barcodes, require multiple scan lines to agree:

auto options = ZXing::ReaderOptions()
    .setMinLineCount(3);  // Default is 2

Higher values increase accuracy but may miss valid barcodes.

Code 39 Extended Mode

Enable full ASCII support for Code 39:

auto options = ZXing::ReaderOptions()
    .setTryCode39ExtendedMode(true);

EAN/UPC Add-On Handling

Control how EAN-2 and EAN-5 add-on symbols are handled:

enum class EanAddOnSymbol {
    Ignore,  // Ignore add-on symbols (default)
    Read,    // Read add-on if present
    Require  // Require add-on to be present
};

Usage:

auto options = ZXing::ReaderOptions()
    .setEanAddOnSymbol(ZXing::EanAddOnSymbol::Read);

auto barcode = ZXing::ReadBarcode(image, options);

if (barcode.isValid()) {
    // Main barcode data
    std::cout << "Main: " << barcode.text() << "\n";

    // Add-on data (if present)
    auto addOn = ZXing::GTIN::EanAddOn(barcode);
    if (!addOn.empty()) {
        std::cout << "Add-on: " << addOn << "\n";
    }
}

Format-Specific Considerations

QR Code, Data Matrix, Aztec

These 2D codes support:

  • Rotation detection (any angle)
  • Perspective correction
  • Damaged code recovery (via error correction)
  • Mirroring detection (flipped horizontally)

PDF417

  • Supports multiple rows/columns
  • Structured append for large data
  • Macro PDF417 support

MaxiCode

  • Partial read support only
  • No write support in standard API

DataBar (RSS)

  • DataBar Omnidirectional and Stacked
  • DataBar Expanded and Expanded Stacked
  • DataBar Limited

Performance Considerations

Fastest Settings

For maximum speed when barcode format and quality are known:

auto options = ZXing::ReaderOptions()
    .setFormats(ZXing::BarcodeFormat::QRCode)  // Specific format
    .setTryHarder(false)
    .setTryRotate(false)
    .setTryInvert(false)
    .setTryDownscale(false)
    .setBinarizer(ZXing::Binarizer::BoolCast);  // If image is pre-binarized

Most Accurate Settings

For maximum detection rate when speed is not critical:

auto options = ZXing::ReaderOptions()
    .setFormats(ZXing::BarcodeFormat::Any)
    .setTryHarder(true)
    .setTryRotate(true)
    .setTryInvert(true)
    .setTryDownscale(true)
    .setMaxNumberOfSymbols(20);  // Look for many barcodes

Thread Safety

All reading functions are thread-safe. You can call ReadBarcode or ReadBarcodes from multiple threads simultaneously on different images.

// Safe to use from multiple threads
#pragma omp parallel for
for (int i = 0; i < numImages; ++i) {
    auto barcode = ZXing::ReadBarcode(images[i], options);
    results[i] = barcode;
}

Related

  • Barcode Results - Understanding the returned Barcode objects
  • Reader Configuration - Complete ReaderOptions reference
  • Image Handling - ImageView and image format details
  • Barcode Formats - Supported barcode formats
  • Error Handling - Understanding errors and validation