Out of memory exceptions when converting images to pdf

We are receiving a “java.lang.OutOfMemoryError” during the final save of a PDF after converting certain image files to PDF. Below is the section of code.

    if(chunkCount > 0) {
        result = getResultTarget(ZIP_FORMAT);
        try (OutputStream output = result.getOutputStream()){
            saveAndClearPdf();
            stitchAndCleanChunks(output);
        }
    } else {
        result = getResultTarget(PDF_FORMAT);
        try (OutputStream output = result.getOutputStream()){
            pdf.optimize();
            pdf.optimizeResources(getOptimizationOptions());
            LOGGER.debug("Saving final PDF");
            pdf.save(output);
        }

seb-softmed-18337209-REDACT.zip (240.5 KB)

This is one of the images

@BobScottHSHS,

I have observed the issue shared by you and request you to please provide information about which version of Aspose.Imaging you have used on your end along with Java and Operating System details. I also suggest you to please consider increasing the Java heap size as well on your end to see if the issue persist or not.

We are running the Aspose Total which contains the Aspose.PDF 19.10 and Aspose Imaging 19.11. We have also attempted to incorporate Aspose Imaging 20.3 and received the same results.

The environment is Windows 2016 with Java 8 Update 181.

What would you recommend we increase the heap size to?

@BobScottHSHS,

In my humble suggestion, you may first try to use Aspose.Imaging for Java in a separate application and perform your rendering. We cannot suggest you a heap size as it depends on your machine configurations and type of file used. You may try setting heap size of 4GB or more.

I will attempt in a separate application. In the meantime, did you also attempt to convert the image I uploaded in your system?

@BobScottHSHS,

I request you to please share the working sample code that you have used on your end to reproduce the issue and I will try the same on my end too.

We have a Java based extension that exports different type of content (images, emails, documents…) to PDF format. The extension has been tested with different images and working correctly until we hit a couple edge cases where the extension starts consuming all the host resources (CPU and memory) and after a few hours it breaks in an “OutOfMemoryException”.

The code attached is used to add images to the PDF, there is a method called “addImageStreamToPdf” which takes the image as an InputStream, the PDF document where the image is added, and the image width and height. These last 2 are used to fit the image proportionaly in the PDF page.

With further testing we have noticed that the sample provided fails as described above, but changing the side margins and the maximum width fixes the issue, and the PDF saves without a problem. We have deployed that, but we are worried that other images with different dimensions might hit another edge combination and fail.

Could you look into it and let us know what combinations (margins/image size) should be avoided?

//takes single page tiffs or multi-page
@Test
public void testTiffTransformation() {
    String tiffImgPath = SOURCE_SAMPLE_FOLDER + "singlepagetiff.tif";
    String outputPdfPath = RESULTS_FOLDER + "resultGoodTtiff.pdf";
    addTiffToPdf(tiffImgPath, outputPdfPath);
}

private void addJpegToPdf(String imgPath, String outputPdfPath) {
    com.aspose.pdf.Document pdf = new com.aspose.pdf.Document();
    try (JpegImage jpeg = (JpegImage) Image.load(imgPath);
            ByteArrayOutputStream os = new ByteArrayOutputStream();){
        jpeg.save(os);
        try (ByteArrayInputStream jpegStream = new ByteArrayInputStream(os.toByteArray());){
            addImageStreamToPdf(jpegStream, pdf, jpeg.getWidth(), jpeg.getHeight());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    pdf.save(outputPdfPath);
    pdf.close();
    pdf.dispose();
    assertTrue(true);
}

private void addPngToPdf(String imgPath, String outputPdfPath){
    com.aspose.pdf.Document pdf = new com.aspose.pdf.Document();
    try (PngImage png = (PngImage) Image.load(imgPath);
            ByteArrayOutputStream os = new ByteArrayOutputStream();){
        png.save(os);
        try (ByteArrayInputStream pngStream = new ByteArrayInputStream(os.toByteArray());){
            addImageStreamToPdf(pngStream, pdf, png.getWidth(), png.getHeight());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    pdf.save(outputPdfPath);
    pdf.close();
    pdf.dispose();
    assertTrue(true);
}

private void addTiffToPdf(String imgPath, String outputPdfPath){
    com.aspose.pdf.Document pdf = new com.aspose.pdf.Document();
    TiffFrame[] frames;
    try (TiffImage tiff = (TiffImage) Image.load(imgPath);){
        frames = tiff.getFrames();
        for (TiffFrame frame : frames) {
            try (ByteArrayOutputStream os = new ByteArrayOutputStream();
                    TiffOptions opt = new TiffOptions(TiffExpectedFormat.TiffNoCompressionRgb);){
                frame.save(os, opt);
                try (ByteArrayInputStream tiffStream = new ByteArrayInputStream(os.toByteArray());){
                    addImageStreamToPdf(tiffStream, pdf, frame.getWidth(), frame.getHeight());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    frames = null;
    System.gc();
    pdf.save(outputPdfPath);
    pdf.close();
    pdf.dispose();
    assertTrue(true);
}

private void addImageStreamToPdf(InputStream imageStream, com.aspose.pdf.Document pdf, int width, int height) {
    Page page = pdf.getPages().add();
    page.getPageInfo().getMargin().setBottom(IMG_MARGIN_BOTTOM);
    page.getPageInfo().getMargin().setTop(IMG_MARGIN_TOP);
    page.getPageInfo().getMargin().setLeft(IMG_MARGIN_LEFT);
    page.getPageInfo().getMargin().setRight(IMG_MARGIN_RIGHT);
    double proportionalMaxHeight = height * (MAX_IMG_WIDTH + IMG_MARGIN_LEFT) / width;
    page.setCropBox(new Rectangle(0, 0, MAX_IMG_WIDTH, proportionalMaxHeight));
    com.aspose.pdf.Image image = new com.aspose.pdf.Image();
    page.getParagraphs().add(image);
    image.setImageStream(imageStream);
    try {
        imageStream.close();
        image = null;
        System.gc();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

@BobScottHSHS,

Thank you for sharing the information. I have created an issue with ID IMAGINGJAVA-1646 in our issue tracking system to further investigate the issue. This thread has been linked with the issue so that you may be notified once the issue will be addressed.

Sorry, this file is private. Only visible to topic owner and staff members. link not working

@closen19,

This thread has been shared by @BobScottHSHS so you may not be able to access the information.

Any update on this?

@BobScottHSHS,

I regret to share that the issue is still unresolved. We request for your patience and will share feedback with you as soon as issue will be addressed.

@BobScottHSHS

We have tested the scenario from perspective of Aspose.PDF for Java using v20.6 and were unable to notice any issue. Please check attached generated output and used code snippet:

Document doc = new Document();
// Add a page to pages collection of document
Page page = doc.getPages().add();
// Load the source image file to Stream object
FileInputStream fs = new FileInputStream(dataDir + "seb-softmed-18337209-REDACT.tiff");
// Set margins so image will fit, etc.
page.getPageInfo().getMargin().setBottom(0);
page.getPageInfo().getMargin().setTop(0);
page.getPageInfo().getMargin().setLeft(0);
page.getPageInfo().getMargin().setRight(0);
Image image1 = new Image();
// Add the image into paragraphs collection of the section
page.getParagraphs().add(image1);
// Set the image file stream
image1.setImageStream(fs);
doc.save(dataDir + "seb-softmed-18337209-REDACT.tiff.pdf");

seb-softmed-18337209-REDACT.tiff.pdf (74.5 KB)

Would you kindly make sure to try latest version of the API and in case you still experience any issue, please feel free to let us know.