I've created two examples, one that will work with current iText versions, one that will only work with the next iText version (because I added some functionality).
This is the easiest way (but only available from iText 5.5.1 on):
Image img = Image.getInstance("some.jpg");
img.setCompressionLevel(PdfStream.BEST_COMPRESSION);
As you are passing a JPEG to iText, the filter will be /DCTDecode
. I've reused the existing setCompressionLevel()
method in a way that the stream will be deflated too. You'll have two entries in the filter: /FlateDecode
and /DCTDecode
. This is shown in the
FlateCompressJPEG1Pass example.
As this requires a version of iText that hasn't been officially released yet, I've also created the FlateCompressJPEG2Passes example.
PdfReader reader = new PdfReader(src);
// We assume that there's a single large picture on the first page
PdfDictionary page = reader.getPageN(1);
PdfDictionary resources = page.getAsDict(PdfName.RESOURCES);
PdfDictionary xobjects = resources.getAsDict(PdfName.XOBJECT);
PdfName imgName = xobjects.getKeys().iterator().next();
PRStream imgStream = (PRStream)xobjects.getAsStream(imgName);
imgStream.setData(PdfReader.getStreamBytesRaw(imgStream), true);
PdfArray array = new PdfArray();
array.add(PdfName.FLATEDECODE);
array.add(PdfName.DCTDECODE);
imgStream.put(PdfName.FILTER, array);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
stamper.close();
reader.close();
This code sample post-processes an existing document, it requires more code and it's more error prone: in this short snippet, I assume that there's a single XObject and that this single object is an image. This may not be the case for your PDFs.