Q: I am using the following JAVA snippet to convert PDF pages to
raster images. PDFNet was fantastic so far, but recently I run into a
memory conditions (bad allocation or similar).
It is hard to know what exactly happened from the exception - can you
tell me what went wrong?
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import pdftron.Common.PDFNetException;
import pdftron.PDF.PDFDoc;
import pdftron.PDF.PDFDraw;
import pdftron.PDF.PDFNet;
import pdftron.PDF.Page;
import pdftron.PDF.PageIterator;
import pdftron.SDF.Obj;
import pdftron.SDF.ObjSet;
public class AssemblePdfFromImages implements Printable {
static private String workDir = "temp";
static private String pageFileName = "page";
static private String workPdf = "pdf.pdf";
private File outputPathFile;
ArrayList<String> pagesImages = null;
public boolean flattenPDF(File folder, Job job, String
fileNameToFlatten) {
boolean allDone = false;
// create JPG images from the PDF file pages
String input_path = folder.getAbsolutePath();
String output_path = folder.getAbsolutePath() + "\\" + workDir + "\
\";
try
{
outputPathFile = new File(output_path); // need to create a folder
if (outputPathFile.exists()) {
if (!outputPathFile.isFile()) {
File files[] = outputPathFile.listFiles();
for (int i = 0; i < files.length; i++)
files[i].delete();
}
outputPathFile.delete();
}
outputPathFile.mkdir();
// The first step in every application using PDFNet is to
initialize the
// library and set the path to common PDF resources. The library is
usually
// initialized only once, but calling Initialize() multiple times
is also fine.
PDFNet.initialize();
PDFNet.setResourcesPath("resources");
PDFDraw draw=new PDFDraw(); // PDFDraw class is used to rasterize
PDF pages.
ObjSet hint_set=new ObjSet();
//--------------------------------------------------------------------------------
PDFDoc doc = new PDFDoc((folder.getAbsolutePath() + "\\" +
fileNameToFlatten));
// Initialize the security handler, in case the PDF is encrypted.
doc.initSecurityHandler();
draw.setDPI(400); // Set the output resolution is to 300 DPI.
// Use optional encoder parameter to specify JPEG quality.
Obj encoder_param=hint_set.createDict();
encoder_param.putNumber("Quality", 100);
pagesImages = new ArrayList<String>();
// Traverse all pages in the document.
Debug.debug("Converting pages to jpg-s:");
for (PageIterator itr=doc.getPageIterator(); itr.hasNext() {
Page current=(Page)(itr.next());
String pageName=output_path + pageFileName + current.getIndex() +
".jpg";
Debug.debug(pageName);
draw.export(current, pageName, "JPEG", encoder_param);
pagesImages.add(pageName);
}
Debug.debug("Done.");
draw.destroy(); // < Added
// hint_set.destroy(); // < Added
doc.close();
//// more processing
} catch(Exception e) {
Debug.debug("failed to decode/assemble PDF for flattening!", e);
}
return allDone;
}
------------
A: Because you are repeatedly allocating a new PDFDraw object, you
would need to call pdfdraw.destroy() in order to quickly release the
memory (Java garbage collector may be sluggish to release the memory
in time).
The same applies to .NET programming (PDFDray implements IDispose
interface). You can use 'using' keyword or explicitly call
pdfdraw.Dispose() to immediately release the memory.
Another factor influencing the memory usage is the resolution/DPI at
which you are rasterizing the image. If the DPI is very large you
could potentially run out of memory. In this case you may need to
rasterize the PDF page in tiles, or increase the available memory.