0
# Result Processing
1
2
ZXing-C++ provides comprehensive result metadata through the Result class, including position information, error details, content analysis, and support for structured append sequences.
3
4
## Result Class
5
6
The primary container for barcode detection results.
7
8
```cpp { .api }
9
class Result {
10
public:
11
Result() = default;
12
13
// Validity and status
14
bool isValid() const;
15
const Error& error() const;
16
17
// Basic result data
18
BarcodeFormat format() const;
19
std::string text() const;
20
const ByteArray& bytes() const;
21
ByteArray bytesECI() const;
22
23
// Content analysis
24
ContentType contentType() const;
25
bool hasECI() const;
26
27
// Position and orientation
28
const Position& position() const;
29
void setPosition(Position pos);
30
int orientation() const;
31
bool isMirrored() const;
32
33
// Metadata
34
std::string symbologyIdentifier() const;
35
std::string ecLevel() const;
36
int lineCount() const;
37
bool readerInit() const;
38
39
// Structured append support
40
int sequenceSize() const;
41
int sequenceIndex() const;
42
std::string sequenceId() const;
43
bool isLastInSequence() const;
44
bool isPartOfSequence() const;
45
46
bool operator==(const Result& other) const;
47
};
48
```
49
50
## Error Class
51
52
Detailed error information for failed or partial barcode detection.
53
54
```cpp { .api }
55
class Error {
56
public:
57
enum class Type { None, Format, Checksum, Unsupported };
58
59
Type type() const noexcept;
60
const std::string& msg() const noexcept;
61
explicit operator bool() const noexcept;
62
std::string location() const noexcept;
63
};
64
```
65
66
## Content Types
67
68
```cpp { .api }
69
enum class ContentType {
70
Text, // Plain text content
71
Binary, // Binary data
72
Mixed, // Mixed text and binary
73
GS1, // GS1 standard format
74
ISO15434, // ISO 15434 format
75
UnknownECI // Unknown ECI encoding
76
};
77
```
78
79
## Position and Geometry
80
81
```cpp { .api }
82
using Position = QuadrilateralI;
83
84
template<typename T>
85
class Quadrilateral {
86
public:
87
Point<T> topLeft() const;
88
Point<T> topRight() const;
89
Point<T> bottomLeft() const;
90
Point<T> bottomRight() const;
91
92
double orientation() const; // Angle in degrees
93
};
94
```
95
96
## Structured Append Functions
97
98
Utility functions for handling structured append sequences (multi-part barcodes).
99
100
```cpp { .api }
101
Result MergeStructuredAppendSequence(const Results& results);
102
Results MergeStructuredAppendSequences(const Results& results);
103
```
104
105
## Usage Examples
106
107
### Basic Result Processing
108
109
```cpp
110
#include "ReadBarcode.h"
111
#include "Result.h"
112
113
using namespace ZXing;
114
115
Result result = ReadBarcode(imageView);
116
117
if (result.isValid()) {
118
// Basic information
119
std::cout << "Format: " << ToString(result.format()) << std::endl;
120
std::cout << "Text: " << result.text() << std::endl;
121
std::cout << "Content Type: " << ToString(result.contentType()) << std::endl;
122
123
// Position information
124
Position pos = result.position();
125
std::cout << "Top-left: (" << pos.topLeft().x << ", " << pos.topLeft().y << ")" << std::endl;
126
std::cout << "Orientation: " << result.orientation() << " degrees" << std::endl;
127
} else {
128
std::cout << "No valid barcode found" << std::endl;
129
}
130
```
131
132
### Error Handling
133
134
```cpp
135
Result result = ReadBarcode(imageView);
136
137
if (!result.isValid()) {
138
const Error& error = result.error();
139
140
switch (error.type()) {
141
case Error::Type::None:
142
std::cout << "No barcode detected" << std::endl;
143
break;
144
145
case Error::Type::Format:
146
std::cout << "Format error: " << error.msg() << std::endl;
147
// Barcode detected but format is invalid/corrupted
148
break;
149
150
case Error::Type::Checksum:
151
std::cout << "Checksum error: " << error.msg() << std::endl;
152
// Barcode detected but checksum validation failed
153
// Content might still be usable
154
break;
155
156
case Error::Type::Unsupported:
157
std::cout << "Unsupported feature: " << error.msg() << std::endl;
158
// Feature not supported in this build
159
break;
160
}
161
162
// Some errors may still have partial data
163
if (!result.text().empty()) {
164
std::cout << "Partial data available: " << result.text() << std::endl;
165
}
166
}
167
```
168
169
### Content Analysis
170
171
```cpp
172
Result result = ReadBarcode(imageView);
173
174
if (result.isValid()) {
175
// Analyze content type
176
switch (result.contentType()) {
177
case ContentType::Text:
178
std::cout << "Plain text: " << result.text() << std::endl;
179
break;
180
181
case ContentType::Binary:
182
std::cout << "Binary data, " << result.bytes().size() << " bytes" << std::endl;
183
// Process binary data from result.bytes()
184
break;
185
186
case ContentType::GS1:
187
std::cout << "GS1 barcode: " << result.text() << std::endl;
188
// Parse GS1 application identifiers
189
break;
190
191
case ContentType::Mixed:
192
std::cout << "Mixed content" << std::endl;
193
// Handle both text and binary portions
194
break;
195
196
case ContentType::ISO15434:
197
std::cout << "ISO 15434 format" << std::endl;
198
break;
199
200
case ContentType::UnknownECI:
201
std::cout << "Unknown ECI encoding" << std::endl;
202
break;
203
}
204
205
// Check for Extended Channel Interpretation
206
if (result.hasECI()) {
207
std::cout << "Contains ECI encoding information" << std::endl;
208
ByteArray eciBytes = result.bytesECI();
209
// Process ECI-encoded data
210
}
211
}
212
```
213
214
### Position and Geometry Analysis
215
216
```cpp
217
Result result = ReadBarcode(imageView);
218
219
if (result.isValid()) {
220
Position pos = result.position();
221
222
// Get corner coordinates
223
auto tl = pos.topLeft();
224
auto tr = pos.topRight();
225
auto bl = pos.bottomLeft();
226
auto br = pos.bottomRight();
227
228
std::cout << "Barcode corners:" << std::endl;
229
std::cout << " Top-left: (" << tl.x << ", " << tl.y << ")" << std::endl;
230
std::cout << " Top-right: (" << tr.x << ", " << tr.y << ")" << std::endl;
231
std::cout << " Bottom-left: (" << bl.x << ", " << bl.y << ")" << std::endl;
232
std::cout << " Bottom-right: (" << br.x << ", " << br.y << ")" << std::endl;
233
234
// Calculate barcode dimensions
235
int width = tr.x - tl.x;
236
int height = bl.y - tl.y;
237
std::cout << "Dimensions: " << width << " x " << height << " pixels" << std::endl;
238
239
// Orientation analysis
240
int orientation = result.orientation();
241
std::cout << "Orientation: " << orientation << " degrees" << std::endl;
242
243
if (result.isMirrored()) {
244
std::cout << "Barcode is mirrored" << std::endl;
245
}
246
}
247
```
248
249
### Multiple Results Processing
250
251
```cpp
252
Results results = ReadBarcodes(imageView);
253
254
std::cout << "Found " << results.size() << " barcodes:" << std::endl;
255
256
for (size_t i = 0; i < results.size(); ++i) {
257
const Result& result = results[i];
258
259
std::cout << "Barcode " << (i + 1) << ":" << std::endl;
260
261
if (result.isValid()) {
262
std::cout << " Format: " << ToString(result.format()) << std::endl;
263
std::cout << " Text: " << result.text() << std::endl;
264
265
Position pos = result.position();
266
std::cout << " Position: (" << pos.topLeft().x << ", " << pos.topLeft().y << ")" << std::endl;
267
} else {
268
std::cout << " Error: " << result.error().msg() << std::endl;
269
}
270
}
271
```
272
273
### Metadata and Quality Information
274
275
```cpp
276
Result result = ReadBarcode(imageView);
277
278
if (result.isValid()) {
279
// Symbology identifier (for standards compliance)
280
std::string symId = result.symbologyIdentifier();
281
if (!symId.empty()) {
282
std::cout << "Symbology ID: " << symId << std::endl;
283
}
284
285
// Error correction level (for applicable formats)
286
std::string ecLevel = result.ecLevel();
287
if (!ecLevel.empty()) {
288
std::cout << "Error correction level: " << ecLevel << std::endl;
289
}
290
291
// Line count (for linear barcodes)
292
int lines = result.lineCount();
293
if (lines > 0) {
294
std::cout << "Detected on " << lines << " scan lines" << std::endl;
295
}
296
297
// Reader initialization symbol
298
if (result.readerInit()) {
299
std::cout << "Reader initialization symbol detected" << std::endl;
300
}
301
}
302
```
303
304
### Structured Append Sequences
305
306
```cpp
307
// Read multiple related barcodes (e.g., QR Code sequences)
308
Results results = ReadBarcodes(imageView);
309
310
// Check for structured append sequences
311
for (const Result& result : results) {
312
if (result.isValid() && result.isPartOfSequence()) {
313
std::cout << "Sequence part " << (result.sequenceIndex() + 1)
314
<< " of " << result.sequenceSize() << std::endl;
315
std::cout << "Sequence ID: " << result.sequenceId() << std::endl;
316
317
if (result.isLastInSequence()) {
318
std::cout << "This is the last part of the sequence" << std::endl;
319
}
320
}
321
}
322
323
// Automatically merge structured append sequences
324
Results mergedResults = MergeStructuredAppendSequences(results);
325
326
std::cout << "After merging sequences: " << mergedResults.size() << " results" << std::endl;
327
328
// Manually merge a specific sequence
329
std::vector<Result> sequence;
330
for (const Result& result : results) {
331
if (result.isPartOfSequence() && result.sequenceId() == "target_id") {
332
sequence.push_back(result);
333
}
334
}
335
336
if (!sequence.empty()) {
337
Result merged = MergeStructuredAppendSequence(sequence);
338
if (merged.isValid()) {
339
std::cout << "Merged sequence text: " << merged.text() << std::endl;
340
}
341
}
342
```
343
344
### Binary Data Handling
345
346
```cpp
347
Result result = ReadBarcode(imageView);
348
349
if (result.isValid()) {
350
// Get raw byte data
351
const ByteArray& rawBytes = result.bytes();
352
353
if (result.contentType() == ContentType::Binary) {
354
std::cout << "Binary content (" << rawBytes.size() << " bytes):" << std::endl;
355
356
// Process binary data
357
for (size_t i = 0; i < rawBytes.size(); ++i) {
358
printf("%02X ", rawBytes[i]);
359
if ((i + 1) % 16 == 0) printf("\n");
360
}
361
printf("\n");
362
} else {
363
// Text content - use text() method for proper encoding
364
std::cout << "Text content: " << result.text() << std::endl;
365
std::cout << "Raw bytes (" << rawBytes.size() << " bytes): ";
366
for (uint8_t byte : rawBytes) {
367
printf("%02X ", byte);
368
}
369
printf("\n");
370
}
371
372
// ECI-encoded bytes (if applicable)
373
if (result.hasECI()) {
374
ByteArray eciBytes = result.bytesECI();
375
std::cout << "ECI bytes (" << eciBytes.size() << " bytes)" << std::endl;
376
}
377
}
378
```
379
380
### Result Comparison and Deduplication
381
382
```cpp
383
Results results = ReadBarcodes(imageView);
384
385
// Remove duplicate results (same content and position)
386
Results uniqueResults;
387
for (const Result& result : results) {
388
bool isDuplicate = false;
389
for (const Result& unique : uniqueResults) {
390
if (result == unique) {
391
isDuplicate = true;
392
break;
393
}
394
}
395
if (!isDuplicate) {
396
uniqueResults.push_back(result);
397
}
398
}
399
400
std::cout << "Unique results: " << uniqueResults.size() << std::endl;
401
```
402
403
## Advanced Processing
404
405
### Quality Assessment
406
407
```cpp
408
bool isHighQualityResult(const Result& result) {
409
if (!result.isValid()) return false;
410
411
// Check error correction level for applicable formats
412
if (result.format() == BarcodeFormat::QRCode) {
413
std::string ecLevel = result.ecLevel();
414
// Higher error correction usually indicates better quality
415
return ecLevel == "H" || ecLevel == "Q";
416
}
417
418
// For linear barcodes, more scan lines indicate better quality
419
if (result.format() & BarcodeFormat::LinearCodes) {
420
return result.lineCount() >= 3;
421
}
422
423
return true;
424
}
425
```
426
427
### Position-Based Filtering
428
429
```cpp
430
std::vector<Result> filterByRegion(const Results& results,
431
int minX, int minY, int maxX, int maxY) {
432
std::vector<Result> filtered;
433
434
for (const Result& result : results) {
435
if (result.isValid()) {
436
Position pos = result.position();
437
Point center = pos.topLeft(); // Simplified center calculation
438
439
if (center.x >= minX && center.x <= maxX &&
440
center.y >= minY && center.y <= maxY) {
441
filtered.push_back(result);
442
}
443
}
444
}
445
446
return filtered;
447
}
448
```
449
450
## Best Practices
451
452
1. **Always check isValid()** before accessing result data
453
2. **Handle different error types** appropriately - some may have partial data
454
3. **Use contentType()** to determine proper data processing method
455
4. **Check for structured append** when processing multiple barcodes
456
5. **Store position information** for UI feedback and region-of-interest optimization
457
6. **Consider result quality metrics** (line count, error correction level) for reliability
458
7. **Use ECI data** when available for proper international character handling
459
8. **Implement deduplication** for multiple barcode detection scenarios