Recognition vs Decoding

Recognition vs Decoding

Reading a Complex Barcode is a two-stage process:

  1. Recognition reads the physical barcode symbol from an image.
  2. Decoding interprets the recognized text as a specific Complex Barcode standard.

These two steps are intentionally separate. BarCodeReader recognizes barcode symbols and returns BarCodeResult objects. It does not directly return SwissQRCodetext, HIBCLICCombinedCodetext, MailmarkCodetext, or another typed Complex Barcode object.

The complete source code for this article is available on GitHub:

View RecognitionVsDecoding.java

Recognition reads the barcode symbol

The first step is regular barcode recognition.

BarCodeReader reader = new BarCodeReader(outputPath, DecodeType.QR);
BarCodeResult[] results = reader.readBarCodes();

For Swiss QR, the recognized barcode type is still DecodeType.QR because Swiss QR is encoded as a QR Code symbol.

Assert.assertEquals(results[0].getCodeType(), DecodeType.QR);
Assert.assertEquals(results[0].getCodeText(), sourceCodetext.getConstructedCodetext());

At this stage, the result contains the standardized text, not a typed Swiss QR payment object.

Decoding restores the Complex Barcode object

The second step is Complex Barcode decoding.

SwissQRCodetext decodedCodetext =
        ComplexCodetextReader.tryDecodeSwissQR(results[0].getCodeText());

After decoding, application code can access structured business fields:

String account = decodedCodetext.getBill().getAccount();
double amount = decodedCodetext.getBill().getAmount();
String creditorName = decodedCodetext.getBill().getCreditor().getName();

This is the point where the recognized barcode text becomes a typed Complex Barcode object.

Recognition can succeed while decoding fails

A QR Code can be valid as a barcode symbol but still not be a valid Swiss QR payload.

String plainText = "This is a valid QR Code, but not a Swiss QR payment.";
BarcodeGenerator generator = new BarcodeGenerator(EncodeTypes.QR, plainText);
generator.save(outputPath, BarCodeImageFormat.PNG);

Recognition succeeds:

BarCodeReader reader = new BarCodeReader(outputPath, DecodeType.QR);
BarCodeResult[] results = reader.readBarCodes();

Assert.assertEquals(results[0].getCodeType(), DecodeType.QR);
Assert.assertEquals(results[0].getCodeText(), plainText);

Swiss QR decoding fails because the text does not follow the Swiss QR payment format:

Assert.assertNull(
        ComplexCodetextReader.tryDecodeSwissQR(results[0].getCodeText())
);

This distinction is important for error handling. A failed recognition means the barcode symbol was not found or could not be read. A failed Complex Barcode decoding means the symbol was read, but its text does not match the requested structured format.

Processing model

Image
  |
  v
BarCodeReader
  |
  v
BarCodeResult
  |
  v
ComplexCodetextReader
  |
  v
Typed Complex Barcode object

For Swiss QR, this means:

QR Code image
  |
  v
BarCodeReader
  |
  v
BarCodeResult with DecodeType.QR and code text
  |
  v
ComplexCodetextReader.tryDecodeSwissQR(...)
  |
  v
SwissQRCodetext

When reading Complex Barcode data:

  • first use BarCodeReader with the expected carrier symbology;
  • check that at least one BarCodeResult was returned;
  • check the recognized DecodeType when needed;
  • pass BarCodeResult.getCodeText() to the matching ComplexCodetextReader.tryDecode... method;
  • handle null from tryDecode... as a decoding failure, not as a recognition failure.