decodeGrayscaleFrame method
Decodes barcodes from raw grayscale byte buffer.
Enhanced v3.0: scans across multiple horizontal lines, supports rotation, and implements full EAN-13, Code 128, and QR finder pattern detection.
Implementation
List<BarcodeResult> decodeGrayscaleFrame(
Uint8List gray,
int width,
int height, {
List<BarcodeFormatFilter>? allowedFormats,
bool enableMultiLineScanning = true,
bool enableRotatedScanning = false,
}) {
final results = <BarcodeResult>[];
final seenValues = <String>{};
// Scan across multiple horizontal lines for 1D barcodes
final scanLines = enableMultiLineScanning
? _generateScanLines(height)
: [height ~/ 2];
for (final scanY in scanLines) {
if (scanY < 0 || scanY >= height) continue;
final lineResults = _scan1DBarcodesAtRow(gray, width, height, scanY);
for (final r in lineResults) {
if (!seenValues.contains(r.rawValue)) {
results.add(r);
seenValues.add(r.rawValue);
}
}
}
// Scan for 2D QR Finder Patterns
final qrResults = _scanQrFinderPatterns(gray, width, height);
for (final r in qrResults) {
if (!seenValues.contains(r.rawValue)) {
results.add(r);
seenValues.add(r.rawValue);
}
}
// Optional: scan at 90° rotation for rotated barcodes
if (enableRotatedScanning && results.isEmpty) {
final rotated = _rotateGrayscale90(gray, width, height);
final rotResults = _scan1DBarcodesAtRow(
rotated,
height,
width, // swapped dimensions
width ~/ 2,
);
results.addAll(rotResults);
}
// Filter by allowed formats if specified
if (allowedFormats != null && allowedFormats.isNotEmpty) {
final allowedNames =
allowedFormats.map((f) => f.nameString.toUpperCase()).toSet();
return results
.where((r) => allowedNames.contains(r.format.toUpperCase()))
.toList();
}
return results;
}