0

I'm troubleshooting an issue where drawing an image onto a PDF document using the PDFBox library seems to take an excessive amount of time (compared to PHP where it's almost instantly). The code in question first creates a bar/qr code using Google com.google.zxing library and then adds that to the PDF document in question. Here are the methods in question:

Create the Barcode (one of the examples):

    private static byte[] generateBarCode(String barcodeText, int width, int height, Writer writer, BarcodeFormat barcodeFormat) throws IOException, WriterException {
        if (Objects.isNull(barcodeText) || width <= 0 || height <= 0) {
            throw new IllegalArgumentException(String.format("generateBarCode: wrong input values %s %s %s %s", barcodeText, width, height, barcodeFormat.name()));
        }

        Map<EncodeHintType, Object> hintMap = new EnumMap<>(EncodeHintType.class);
        hintMap.put(EncodeHintType.MARGIN, 0);

        BitMatrix bitMatrix = writer.encode(barcodeText, barcodeFormat, width, height, hintMap);

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        MatrixToImageWriter.writeToStream(bitMatrix, "png", bos);
        bos.close();

        return bos.toByteArray();
    }

This is then passed to the below method as the byte[] image. Draw the image on the PDF Document:

    public static void drawImage(PDPageContentStream contentStream, int x, int y, byte[] image, PDDocument document, Integer width, Integer height) throws IOException {
        ByteArrayInputStream bais = new ByteArrayInputStream(image);
        BufferedImage bim = ImageIO.read(bais);
        PDImageXObject pdImage = LosslessFactory.createFromImage(document, bim);
        if (width != null && height != null) { // if we set the image width/height
            contentStream.drawImage(pdImage, x, y, width, height);
            return;
        }
        contentStream.drawImage(pdImage, x, y);
    }

At time we need to create a PDF with 100s of pages and each page/item will have a different barcode which needs to be created and then drawn, along with a bunch of text and other non-image items. This can take upwards of 10+ minutes for a 1000 page document for example, however if I comment out the barcode generation and just draw an existing image from my classpath it can complete in ~60 seconds (which I still think is too long). If I comment out both then the 1000 document PDF basically gets rendered instantly from the template and adding all my text.

Is there a better way of doing this that I am overlooking?

Terry Sposato
  • 572
  • 2
  • 7
  • have you tried increasing the amount of memory allocated to JVM – DevZer0 Nov 23 '21 at 05:51
  • Try creating vector graphics. Each active bit in the matrix is a 1x1 rectangle. https://stackoverflow.com/questions/10789059/create-qr-code-in-vector-image – Tilman Hausherr Nov 23 '21 at 07:10
  • I ended up converting most of my barcode generation methods to return a BufferedImage and I am using that directly in the PDFBox drawImage which has significantly sped up things. Still takes a little longer than I would like, I'll investigate the vector graphics next. – Terry Sposato Nov 23 '21 at 23:48

0 Answers0