Search code examples
javabarcodezxingcode39

ZXing - Read Code 39 barcode without check digit


I'm using ZXing library for reading Code 39 barcodes from pdf documents. I noticed it adds a control character at the end of the barcode.

Is there a way to disable the generation of that extra character?

Here is my code snippet:

public Optional<String> readBarcode(File docFile){
    try (PDDocument document = PDDocument.load(docFile)) {
        PDFRenderer pdfRenderer = new PDFRenderer(document);
        BufferedImage fullPageImage = pdfRenderer.renderImageWithDPI(0, 300, ImageType.RGB);
        int imageWidth = fullPageImage.getWidth();
        int imageHeight = fullPageImage.getHeight();
        int sectionWidth = 800;
        int sectionHeight = 800;
        int scanDelta = 200;
        int x = imageWidth - sectionWidth;
        int y = 0;
        int w = sectionWidth;
        int h = sectionHeight;
        int sectionNumber = 1;
        int rowIndex = 1;
        int columnIndex = 1;
        // Configuring ZXing
        Map<DecodeHintType, Object> zxingHints = new HashMap<>();
        zxingHints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
        zxingHints.put(DecodeHintType.POSSIBLE_FORMATS, List.of(BarcodeFormat.CODE_39));
        do {
            do {
                BufferedImage imageSection = fullPageImage.getSubimage(x, y, w, h);
                BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(imageSection)));
                try {
                    Result barcodeDecodingResult = new MultiFormatReader().decode(binaryBitmap, zxingHints);
                    if (StringUtils.isNotBlank(barcodeDecodingResult.getText())) {
                        // Retrieving barcode 
                        return Optional.of(barcodeDecodingResult.getText());
                    }
                } catch (NotFoundException ignored) {}
                x = Math.max(0, x - scanDelta);
                sectionNumber++;
                columnIndex++;
            } while (x > 0);
            y = Math.min(imageHeight, y + scanDelta);
            x = imageWidth - sectionWidth;
            columnIndex = 1;
            rowIndex++;
        } while ((y + sectionHeight) < imageHeight);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
    return Optional.empty();
}

Solution

  • I solved setting a configuration of the DecodeHintType structure.

    In particular, when setting ASSUME_CODE_39_CHECK_DIGIT as false, the generation of check digit is disabled.

    zxingHints.put(DecodeHintType.ASSUME_CODE_39_CHECK_DIGIT, Boolean.FALSE);
    

    So, the complete configuration is:

    Map<DecodeHintType, Object> zxingHints = new HashMap<>();
    zxingHints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
    zxingHints.put(DecodeHintType.POSSIBLE_FORMATS, List.of(BarcodeFormat.CODE_39));
    zxingHints.put(DecodeHintType.ASSUME_CODE_39_CHECK_DIGIT, Boolean.FALSE);
    

    More info here