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++

images.mddocs/reference/

Image Handling

ZXing-C++ uses the ImageView and Image classes to handle image data in various pixel formats. These classes provide a lightweight, efficient interface for passing image data to the library without requiring external dependencies.

ImageView Class

ImageView is a non-owning view of image data. It does not copy or manage the memory, just provides access to existing data.

class ImageView {
public:
    // Constructors
    ImageView();  // Default null view

    ImageView(const uint8_t* data, int width, int height, ImageFormat format,
              int rowStride = 0, int pixStride = 0);

    ImageView(const uint8_t* data, int size, int width, int height,
              ImageFormat format, int rowStride = 0, int pixStride = 0);  // With bounds checking

    // Properties
    int width() const;
    int height() const;
    int pixStride() const;
    int rowStride() const;
    ImageFormat format() const;

    // Data access
    const uint8_t* data() const;
    const uint8_t* data(int x, int y) const;

    // Transformations (return new views, no copy)
    ImageView cropped(int left, int top, int width, int height) const;
    ImageView rotated(int degree) const;  // 0, 90, 180, 270
    ImageView subsampled(int scale) const;
};

Image Class

Image extends ImageView and owns its memory. Use this when you need the library to manage image data.

class Image : public ImageView {
public:
    Image();  // Default empty
    Image(int w, int h, ImageFormat f = ImageFormat::Lum);  // Allocate new image
};

Image Formats

enum class ImageFormat : uint32_t {
    None,     // Invalid format
    Lum,      // Grayscale (luminance only)
    LumA,     // Grayscale + Alpha
    RGB,      // Red-Green-Blue
    BGR,      // Blue-Green-Red
    RGBA,     // Red-Green-Blue-Alpha
    ARGB,     // Alpha-Red-Green-Blue
    BGRA,     // Blue-Green-Red-Alpha
    ABGR      // Alpha-Blue-Green-Red
};

Format Details

FormatBytes/PixelChannel OrderNotes
Lum1GrayscaleMost efficient for reading
LumA2Gray, AlphaRarely used
RGB3Red, Green, BlueStandard RGB
BGR3Blue, Green, RedCommon in OpenCV
RGBA4Red, Green, Blue, AlphaStandard RGBA
ARGB4Alpha, Red, Green, BlueWindows DIB format
BGRA4Blue, Green, Red, AlphaCommon in graphics APIs
ABGR4Alpha, Blue, Green, RedLess common

Usage Examples

Basic ImageView Creation

// From grayscale data
uint8_t* grayData = /* ... */;
int width = 640;
int height = 480;

auto imageView = ZXing::ImageView(grayData, width, height, ZXing::ImageFormat::Lum);

// Read barcode
auto barcode = ZXing::ReadBarcode(imageView);

RGB Image

// From RGB data (e.g., from image file)
uint8_t* rgbData = /* ... */;  // width * height * 3 bytes
int width = 640;
int height = 480;

auto imageView = ZXing::ImageView(rgbData, width, height, ZXing::ImageFormat::RGB);

auto barcode = ZXing::ReadBarcode(imageView);

RGBA Image

// From RGBA data (e.g., from PNG with alpha)
uint8_t* rgbaData = /* ... */;  // width * height * 4 bytes
int width = 800;
int height = 600;

auto imageView = ZXing::ImageView(rgbaData, width, height, ZXing::ImageFormat::RGBA);

auto barcodes = ZXing::ReadBarcodes(imageView);

BGR Image (OpenCV)

OpenCV uses BGR format by default:

#include <opencv2/opencv.hpp>

cv::Mat cvImage = cv::imread("image.jpg");

auto imageView = ZXing::ImageView(
    cvImage.data,
    cvImage.cols,
    cvImage.rows,
    ZXing::ImageFormat::BGR,
    cvImage.step  // rowStride
);

auto barcode = ZXing::ReadBarcode(imageView);

Custom Stride

When your image has padding or non-standard layout:

// Image with row padding
uint8_t* data = /* ... */;
int width = 640;
int height = 480;
int rowStride = 672;  // 640 * 3 + 32 bytes padding
int pixStride = 3;     // RGB

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

Bounds-Checked Construction

// If you know the buffer size, use bounds-checking constructor
uint8_t* data = /* ... */;
int bufferSize = 1024 * 768 * 3;
int width = 1024;
int height = 768;

try {
    auto imageView = ZXing::ImageView(
        data, bufferSize, width, height,
        ZXing::ImageFormat::RGB
    );
} catch (const std::invalid_argument& e) {
    std::cerr << "Invalid image parameters: " << e.what() << "\n";
}

Image Transformations

Cropping

Extract a region of interest without copying:

auto fullImage = ZXing::ImageView(data, width, height, ZXing::ImageFormat::Lum);

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

// roi is a view into the same data, no copy
auto barcode = ZXing::ReadBarcode(roi);

Crop parameters are automatically clamped to valid ranges.

Rotation

Create rotated views (no copy):

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

// Rotate 90 degrees clockwise
auto rotated90 = image.rotated(90);

// Rotate 180 degrees
auto rotated180 = image.rotated(180);

// Rotate 270 degrees (90 counter-clockwise)
auto rotated270 = image.rotated(270);

// No rotation
auto rotated0 = image.rotated(0);  // Returns copy of view

Rotation is achieved by adjusting strides and starting pointer, not by copying pixels.

Downsampling

Subsample for faster processing:

auto image = ZXing::ImageView(data, 3200, 2400, ZXing::ImageFormat::Lum);

// Downsample by factor of 4
auto downsampled = image.subsampled(4);  // Now 800x600

// This is a view with adjusted strides, skipping pixels
auto barcode = ZXing::ReadBarcode(downsampled);

Image Class (Owning)

When you need to allocate and own image memory:

// Allocate a new grayscale image
ZXing::Image image(640, 480, ZXing::ImageFormat::Lum);

// Access mutable data
uint8_t* data = const_cast<uint8_t*>(image.data());

// Fill with pattern
for (int y = 0; y < image.height(); ++y) {
    for (int x = 0; x < image.width(); ++x) {
        data[y * image.width() + x] = (x + y) % 256;
    }
}

// Use like ImageView
auto barcode = ZXing::ReadBarcode(image);

Image from WriteBarcodeToImage

The writing API returns an Image:

auto barcode = ZXing::CreateBarcodeFromText("Test", options);
auto image = ZXing::WriteBarcodeToImage(barcode);

// image owns its memory
int width = image.width();
int height = image.height();

// Get pixel data (grayscale)
const uint8_t* pixels = image.data();

// Save to file, display, etc.

Format Utilities

// Get pixel stride for format
constexpr int PixStride(ImageFormat format);

// Get color channel indices
constexpr int RedIndex(ImageFormat format);
constexpr int GreenIndex(ImageFormat format);
constexpr int BlueIndex(ImageFormat format);

// Convert RGB to grayscale
constexpr uint8_t RGBToLum(unsigned r, unsigned g, unsigned b);

Usage:

auto format = ZXing::ImageFormat::RGB;
int stride = ZXing::PixStride(format);  // 3

int rIndex = ZXing::RedIndex(format);   // 0
int gIndex = ZXing::GreenIndex(format); // 1
int bIndex = ZXing::BlueIndex(format);  // 2

// Manual grayscale conversion
uint8_t gray = ZXing::RGBToLum(r, g, b);

Data Layout

Pixel Access

For grayscale (Lum):

uint8_t pixel = data[y * width + x];

For RGB:

int offset = (y * width + x) * 3;
uint8_t r = data[offset + 0];
uint8_t g = data[offset + 1];
uint8_t b = data[offset + 2];

For RGBA:

int offset = (y * width + x) * 4;
uint8_t r = data[offset + 0];
uint8_t g = data[offset + 1];
uint8_t b = data[offset + 2];
uint8_t a = data[offset + 3];

With custom stride:

uint8_t pixel = data[y * rowStride + x * pixStride];

Using data(x, y) Helper

auto imageView = ZXing::ImageView(data, width, height, format);

// Get pointer to pixel at (x, y)
const uint8_t* pixelPtr = imageView.data(x, y);

// For RGB
uint8_t r = pixelPtr[0];
uint8_t g = pixelPtr[1];
uint8_t b = pixelPtr[2];

Integration Examples

Qt QImage

QImage qImage = /* ... */;

// Ensure RGB32 or ARGB32 format
qImage = qImage.convertToFormat(QImage::Format_RGB888);

auto imageView = ZXing::ImageView(
    qImage.bits(),
    qImage.width(),
    qImage.height(),
    ZXing::ImageFormat::RGB,
    qImage.bytesPerLine()
);

auto barcode = ZXing::ReadBarcode(imageView);

OpenCV Mat

cv::Mat mat = /* ... */;

// Grayscale
if (mat.channels() == 1) {
    auto imageView = ZXing::ImageView(
        mat.data, mat.cols, mat.rows,
        ZXing::ImageFormat::Lum,
        mat.step
    );
}
// BGR
else if (mat.channels() == 3) {
    auto imageView = ZXing::ImageView(
        mat.data, mat.cols, mat.rows,
        ZXing::ImageFormat::BGR,
        mat.step
    );
}
// BGRA
else if (mat.channels() == 4) {
    auto imageView = ZXing::ImageView(
        mat.data, mat.cols, mat.rows,
        ZXing::ImageFormat::BGRA,
        mat.step
    );
}

STB Image

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

int width, height, channels;
unsigned char* data = stbi_load("image.png", &width, &height, &channels, 0);

ZXing::ImageFormat format;
if (channels == 1) format = ZXing::ImageFormat::Lum;
else if (channels == 3) format = ZXing::ImageFormat::RGB;
else if (channels == 4) format = ZXing::ImageFormat::RGBA;

auto imageView = ZXing::ImageView(data, width, height, format);
auto barcode = ZXing::ReadBarcode(imageView);

stbi_image_free(data);

Performance Tips

  1. Use Grayscale: Convert to grayscale before passing to ZXing for best performance
  2. Avoid Copies: Use ImageView for zero-copy operation
  3. Crop ROI: If barcode location is known, crop to region of interest
  4. Downsample Large Images: For very large images, use subsampled() or pre-downscale
  5. Reuse Buffers: Allocate image buffers once and reuse them

Error Handling

Invalid Parameters

try {
    // This will throw if data is nullptr
    auto view = ZXing::ImageView(nullptr, 100, 100, ZXing::ImageFormat::Lum);
} catch (const std::invalid_argument& e) {
    std::cerr << "Error: " << e.what() << "\n";
}

try {
    // This will throw if width/height is <= 0
    auto view = ZXing::ImageView(data, 0, 0, ZXing::ImageFormat::Lum);
} catch (const std::invalid_argument& e) {
    std::cerr << "Error: " << e.what() << "\n";
}

Bounds Checking

Use the size-parameter constructor for automatic bounds validation:

std::vector<uint8_t> buffer(640 * 480);

try {
    // This validates buffer is large enough
    auto view = ZXing::ImageView(
        buffer.data(), buffer.size(),
        640, 480, ZXing::ImageFormat::Lum
    );
} catch (const std::invalid_argument& e) {
    std::cerr << "Buffer too small: " << e.what() << "\n";
}

Related

  • Barcode Reading - Using ImageView for reading
  • Barcode Writing - Image output from writing
  • Reader Configuration - Reading options that affect image processing