Q:
I'd like to implement a similar function to Acrobat's option 'Optimize
PDF' in my program. It should make the PDF as small as possible but
still have acceptable quality for screen. The optimized PDF will not
be used for printing afterwards.
I found the JBIGTest sample for shrinking monochrome images, but I'd
like do this for color images too. I'd like to make a decission based
on the DPI but I can't find those values in the PDF Reference.
Since your site mentions PDF optimizing as a common use case scenario,
I was hoping you could give me some hints to implement this.
----
A:
If need to develop PDF optimization functions, JBIG2 sample project is
a good place to look at. You could extend this code to handle color
images (e.g. for down-sampling and recompression), embedded fonts
(e.g. for subsetting or removal of embedded fonts), etc.
Because the same image may be reused multiple times on a given PDF
page (or throughout the document), PDF format does not specify DPI
(Dots Per Inch) parameter as part of the image dictionary.
DPI of an image drawn on a page depends on several factors:
- image pixel dimensions (i.e. pdftron.PDF.Image.GetImageWidth() &
Height()).
- the area of the PDF page covered with the image (this can be
obtained from current transformation matrix (CTM) of a given image
Element). Let's assume that this area is: element_width x
element_height.
So the DPI of the given image instance is: [element_width/
image.GetImageWidth(), element_height/image.GetImageheight()].
For example, if the same image is drawn twice the size on one page
relative to another page, the effective DPI of the larger image will
be two times smaller.
For more information on this topic please see the following FAQ
entry:
How do I get the image resolution and DPI? http://www.pdftron.com/net/faq.html#img_01
Using PDFNet, you can calculate the effective DPI for every instance
of 'PDF.Image' on the page and you can use this information in your
sub-sampling function.
The sub-sampling function can read image data using
pdftron.PDF.Image.Export or GetBitmap()). After subsampling you can
create a new image using PDF.Image.Create(...) and you can swap the
original image with the new instance using
(sdfdoc.Swap(old_imgage.GetObjNum(), new_imgage.GetObjNum(); i.e.
similar to JBIG2 sample code)).