0
# Barcode Reading
1
2
ZXing-C++ provides comprehensive barcode reading capabilities through a simple yet powerful API. The library can detect and decode over 20 different barcode formats from various image sources with configurable accuracy and performance trade-offs.
3
4
## Core Reading Functions
5
6
### Single Barcode Reading
7
8
```cpp { .api }
9
ZXing::Barcode ReadBarcode(const ImageView& image, const ReaderOptions& options = {});
10
```
11
12
Reads a single barcode from an image. Returns the first valid barcode found, or an invalid result if no barcodes are detected.
13
14
**Parameters:**
15
- `image`: ImageView containing the image data to scan
16
- `options`: Optional ReaderOptions to customize detection behavior
17
18
**Returns:** `Barcode` object containing decoded information or error details
19
20
### Multiple Barcode Reading
21
22
```cpp { .api }
23
ZXing::Barcodes ReadBarcodes(const ImageView& image, const ReaderOptions& options = {});
24
```
25
26
Reads multiple barcodes from a single image. Continues scanning until the maximum number of symbols is reached or no more barcodes are found.
27
28
**Parameters:**
29
- `image`: ImageView containing the image data to scan
30
- `options`: Optional ReaderOptions to customize detection behavior
31
32
**Returns:** `std::vector<Barcode>` containing all detected barcodes
33
34
## Usage Examples
35
36
### Basic Reading
37
38
```cpp
39
#include "ZXing/ReadBarcode.h"
40
41
// Load image data (implementation depends on your image library)
42
auto image = ZXing::ImageView(data, width, height, ZXing::ImageFormat::RGB);
43
44
// Read with default options
45
auto result = ZXing::ReadBarcode(image);
46
if (result.isValid()) {
47
std::cout << "Found: " << result.text() << std::endl;
48
std::cout << "Format: " << ZXing::ToString(result.format()) << std::endl;
49
}
50
```
51
52
### Optimized Reading
53
54
```cpp
55
// Configure for specific use case
56
auto options = ZXing::ReaderOptions()
57
.setFormats(ZXing::BarcodeFormat::QRCode | ZXing::BarcodeFormat::EAN13)
58
.setTryHarder(false) // Prioritize speed
59
.setTryRotate(false) // Don't try rotations
60
.setMaxNumberOfSymbols(1); // Stop after first barcode
61
62
auto result = ZXing::ReadBarcode(image, options);
63
```
64
65
### Multiple Barcode Scanning
66
67
```cpp
68
auto options = ZXing::ReaderOptions()
69
.setMaxNumberOfSymbols(10) // Allow up to 10 barcodes
70
.setReturnErrors(true); // Include barcodes with errors
71
72
auto results = ZXing::ReadBarcodes(image, options);
73
for (const auto& barcode : results) {
74
if (barcode.isValid()) {
75
std::cout << "Valid: " << barcode.text() << std::endl;
76
} else {
77
std::cout << "Error: " << barcode.error().msg() << std::endl;
78
}
79
}
80
```
81
82
### Format-Specific Reading
83
84
```cpp
85
// Only scan for specific formats
86
auto qrOptions = ZXing::ReaderOptions()
87
.setFormats(ZXing::BarcodeFormat::QRCode |
88
ZXing::BarcodeFormat::MicroQRCode |
89
ZXing::BarcodeFormat::RMQRCode);
90
91
auto linearOptions = ZXing::ReaderOptions()
92
.setFormats(ZXing::BarcodeFormat::LinearCodes);
93
94
auto matrixOptions = ZXing::ReaderOptions()
95
.setFormats(ZXing::BarcodeFormat::MatrixCodes);
96
```
97
98
### High-Accuracy Reading
99
100
```cpp
101
// Maximum accuracy configuration
102
auto accurateOptions = ZXing::ReaderOptions()
103
.setTryHarder(true) // More intensive scanning
104
.setTryRotate(true) // Try all rotations
105
.setTryInvert(true) // Try inverted images
106
.setTryDownscale(true) // Try different scales
107
.setBinarizer(ZXing::Binarizer::LocalAverage)
108
.setMinLineCount(2); // Require at least 2 line confirmations
109
110
auto result = ZXing::ReadBarcode(image, accurateOptions);
111
```
112
113
### Performance-Optimized Reading
114
115
```cpp
116
// Maximum speed configuration
117
auto fastOptions = ZXing::ReaderOptions()
118
.setTryHarder(false)
119
.setTryRotate(false)
120
.setTryInvert(false)
121
.setTryDownscale(false)
122
.setIsPure(true) // Assume clean, perfectly aligned barcode
123
.setBinarizer(ZXing::Binarizer::BoolCast) // Fastest binarizer
124
.setMaxNumberOfSymbols(1); // Stop after first find
125
126
auto result = ZXing::ReadBarcode(image, fastOptions);
127
```
128
129
## Result Analysis
130
131
### Checking Validity
132
133
```cpp
134
auto result = ZXing::ReadBarcode(image);
135
136
if (result.isValid()) {
137
// Successfully decoded
138
std::string text = result.text();
139
ZXing::BarcodeFormat format = result.format();
140
} else {
141
// Failed to decode or error occurred
142
auto error = result.error();
143
std::cout << "Error: " << error.msg() << std::endl;
144
145
// Check error type
146
switch (error.type()) {
147
case ZXing::Error::Format:
148
std::cout << "Format-related error" << std::endl;
149
break;
150
case ZXing::Error::Checksum:
151
std::cout << "Checksum validation failed" << std::endl;
152
break;
153
case ZXing::Error::Unsupported:
154
std::cout << "Unsupported feature" << std::endl;
155
break;
156
}
157
}
158
```
159
160
### Accessing Metadata
161
162
```cpp
163
auto result = ZXing::ReadBarcode(image);
164
if (result.isValid()) {
165
// Basic information
166
std::string text = result.text();
167
ZXing::BarcodeFormat format = result.format();
168
ZXing::ContentType contentType = result.contentType();
169
170
// Position and orientation
171
auto position = result.position();
172
int orientation = result.orientation();
173
bool mirrored = result.isMirrored();
174
bool inverted = result.isInverted();
175
176
// Advanced metadata
177
std::string ecLevel = result.ecLevel();
178
std::string version = result.version();
179
std::string symbologyId = result.symbologyIdentifier();
180
bool hasECI = result.hasECI();
181
182
// Raw data access
183
const ZXing::ByteArray& rawBytes = result.bytes();
184
ZXing::ByteArray eciBytes = result.bytesECI();
185
}
186
```
187
188
### Text Mode Handling
189
190
```cpp
191
// Configure text rendering mode
192
auto options = ZXing::ReaderOptions()
193
.setTextMode(ZXing::TextMode::HRI); // Human Readable Interpretation
194
195
auto result = ZXing::ReadBarcode(image, options);
196
197
// Or specify mode when getting text
198
std::string plainText = result.text(ZXing::TextMode::Plain);
199
std::string eciText = result.text(ZXing::TextMode::ECI);
200
std::string hriText = result.text(ZXing::TextMode::HRI);
201
std::string hexText = result.text(ZXing::TextMode::Hex);
202
std::string escapedText = result.text(ZXing::TextMode::Escaped);
203
```
204
205
## Structured Append Sequences
206
207
Some barcode formats support splitting data across multiple symbols. ZXing-C++ provides utilities to handle these sequences:
208
209
### Detecting Sequences
210
211
```cpp
212
auto results = ZXing::ReadBarcodes(image);
213
for (const auto& barcode : results) {
214
if (barcode.isPartOfSequence()) {
215
int sequenceSize = barcode.sequenceSize();
216
int sequenceIndex = barcode.sequenceIndex();
217
std::string sequenceId = barcode.sequenceId();
218
bool isLast = barcode.isLastInSequence();
219
220
std::cout << "Part " << (sequenceIndex + 1)
221
<< " of " << sequenceSize << std::endl;
222
}
223
}
224
```
225
226
### Merging Sequences
227
228
```cpp
229
// Manually merge a specific sequence
230
std::vector<ZXing::Barcode> sequence = {/* collect sequence parts */};
231
auto merged = ZXing::MergeStructuredAppendSequence(sequence);
232
233
// Automatically merge all complete sequences
234
auto results = ZXing::ReadBarcodes(image);
235
auto mergedResults = ZXing::MergeStructuredAppendSequences(results);
236
```
237
238
## Error Handling
239
240
### Comprehensive Error Checking
241
242
```cpp
243
auto result = ZXing::ReadBarcode(image);
244
245
if (!result.isValid()) {
246
const auto& error = result.error();
247
248
std::cout << "Error Type: ";
249
switch (error.type()) {
250
case ZXing::Error::None:
251
std::cout << "No error (but no barcode found)";
252
break;
253
case ZXing::Error::Format:
254
std::cout << "Format error - " << error.msg();
255
break;
256
case ZXing::Error::Checksum:
257
std::cout << "Checksum error - " << error.msg();
258
break;
259
case ZXing::Error::Unsupported:
260
std::cout << "Unsupported feature - " << error.msg();
261
break;
262
}
263
std::cout << std::endl;
264
}
265
```
266
267
### Including Errors in Results
268
269
```cpp
270
// Include barcodes with errors in results
271
auto options = ZXing::ReaderOptions().setReturnErrors(true);
272
auto results = ZXing::ReadBarcodes(image, options);
273
274
for (const auto& result : results) {
275
if (result.isValid()) {
276
std::cout << "Valid: " << result.text() << std::endl;
277
} else if (result.error()) {
278
std::cout << "Invalid: " << result.error().msg() << std::endl;
279
// You might still want to use some metadata
280
std::cout << "Format: " << ZXing::ToString(result.format()) << std::endl;
281
}
282
}
283
```
284
285
## Thread Safety
286
287
Reading operations are thread-safe as long as each thread uses its own `ReaderOptions` instance and processes different `ImageView` objects:
288
289
```cpp
290
#include <thread>
291
#include <vector>
292
293
void processImage(const ZXing::ImageView& image, const ZXing::ReaderOptions& options) {
294
auto result = ZXing::ReadBarcode(image, options);
295
// Process result...
296
}
297
298
int main() {
299
std::vector<std::thread> threads;
300
301
for (int i = 0; i < numImages; ++i) {
302
threads.emplace_back([&images, i]() {
303
auto options = ZXing::ReaderOptions(); // Each thread gets its own options
304
processImage(images[i], options);
305
});
306
}
307
308
for (auto& thread : threads) {
309
thread.join();
310
}
311
}
312
```