In a Java backend server application I want to decode a QR code embedded into a PDF file using the zxing library. I adapted the example from https://gist.github.com/JoelGeraci-Datalogics/dd9e214d4c584d61f5b1 to work with the pdfbox library as follows:
ReadBarcodeFromPDF.java
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
public class ReadBarcodeFromPDF {
private static final List<String> urlList = Arrays.asList(
"http://dev.datalogics.com/cookbook/forms/ReadBarcodeImage_QRCode.pdf",
"http://dev.datalogics.com/cookbook/forms/ReadBarcodeImage_DataMatrix.pdf",
"http://dev.datalogics.com/cookbook/forms/ReadBarcodeImage_PDF417.pdf"
);
public static void main(String[] args) throws Exception {
for (String url : urlList) {
readCode(url);
}
}
private static String readCode(String url) throws MalformedURLException, IOException, NotFoundException {
URLConnection connection = new URL(url).openConnection();
connection.connect();
try (InputStream inputStream = connection.getInputStream()) {
try (PDDocument document = PDDocument.load(inputStream)) {
PDFRenderer pdfRenderer = new PDFRenderer(document);
BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(0, 300, ImageType.BINARY);
LuminanceSource luminanceSource = new BufferedImageLuminanceSource(bufferedImage);
HybridBinarizer hybridBinarizer = new HybridBinarizer(luminanceSource);
BinaryBitmap bitmap = new BinaryBitmap(hybridBinarizer);
MultiFormatReader reader = new MultiFormatReader();
Hashtable<DecodeHintType, Object> hints = new Hashtable<>();
hints.put(DecodeHintType.POSSIBLE_FORMATS, Arrays.asList(
BarcodeFormat.QR_CODE,
BarcodeFormat.DATA_MATRIX,
BarcodeFormat.PDF_417
));
hints.put(DecodeHintType.PURE_BARCODE, Boolean.FALSE);
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
reader.setHints(hints);
Result result = reader.decodeWithState(bitmap);
return result.getText();
}
}
}
}
The example is supposed to recognize codes from PDF documents with different code types:
But it fact it recognizes only the PDF417. The QR Code (in which I am interested) and the data matrix (in which I am not interested) are not recognized.
The output is
com.google.zxing.NotFoundException
com.google.zxing.NotFoundException
11/15/2010 Tony Blue
I also tried
Different arguments in line
pdfRenderer.renderImageWithDPI(0, 300, ImageType.BINARY);
dpi
(2nd argument) between 100
and 300
imageType
(3rd argument)pom.xml
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.26</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.3</version>
</dependency>
Your code works if one removes
hints.put(DecodeHintType.PURE_BARCODE, Boolean.FALSE);
I suspect that ZXIng only checks whether there is an entry for the key and not its value. The javadoc mentions "Doesn't matter what it maps to; use Boolean.TRUE."