Q: Reusing form XObjects helps somewhat, however the transtormed PDFs
are still much larger than the original documents.
I use the following function to place scaled and translated PDF page
on a new page. Can you please suggest any other ways to decrease the
file size of generated documents:
public void Transform(double dblX, double dblY, double
dblScale)
{
try
{
// Create new page
Page page = m_doc.PageCreate(m_page.GetMediaBox());
page.SetRotation(m_page.GetRotation());
// Get current page index
int iPage = m_page.GetIndex();
ElementBuilder builder = new ElementBuilder();
ElementWriter writer = new ElementWriter();
writer.Begin(page);
builder.Reset();
// Create form that contains page contents
Element element = builder.CreateForm(m_page, m_doc);
Matrix2D matrix = new Matrix2D(dblScale, 0, 0, dblScale, dblX,
dblY);
element.GetGState().SetTransform(matrix);
writer.WritePlacedElement(element);
// Finish writing to page
writer.End();
writer.Dispose();
// Copy annotations to new page and position based on
scaling
int iCount = m_page.GetNumAnnots();
for (int i = 0; i < iCount; i++)
{
Annot annotOld = m_page.GetAnnot(i);
Annot annot = new Annot(annotOld.GetSDFObj());
Rect rect = annot.GetRect();
double dblWidth = rect.Width();
double dblHeight = rect.Height();
// Shift and scale rect x-coordinate
rect.x1 = dblX + (rect.x1 * dblScale);
rect.x2 = rect.x1 + (dblWidth * dblScale);
// Shift and scale rect y-coordinate
rect.y1 = dblY + (rect.y1 * dblScale);
rect.y2 = rect.y1 + (dblHeight * dblScale);
// See if changing scale
if (dblScale != 1.0)
{
Annot.BorderStyle style = annot.GetBorderStyle
();
if (style.width > 0)
{
// Scale border width (but minimum is one)
dblWidth = style.width * dblScale;
dblWidth = ((dblWidth - Math.Floor
(dblWidth) > 0.5) ? Math.Ceiling(dblWidth) : Math.Floor(dblWidth));
style.width = Math.Min(1, (int) dblWidth);
annot.SetBorderStyle(style);
}
}
// Change rectangle
annot.SetRect(rect);
page.AnnotPushBack(annot);
}
// Replace current page with transformed page
PageIterator iterPage = m_doc.GetPageIterator(iPage);
m_doc.PageInsert(iterPage, page);
m_doc.GetSDFDoc().Swap(m_page.GetSDFObj().GetObjNum(),
page.GetSDFObj().GetObjNum());
m_doc.PageRemove(m_doc.GetPageIterator(iPage));
// Use new page
m_page = m_doc.GetPage(iPage);
}
catch(Exception ex)
{
throw PDFManager.Exception(“Unable to transform
page.”, ex);
}
}
A: The increase in file size from ‘Transformed.pdf’ to
‘TransformedOverlayed.pdf’ is solely due to repeated form xobjects (as
discussed in the previous email).
The increase in file size from ‘Original.pdf’ to ‘Transformed.pdf’ is
due to dead references (as expected).
To detect this we wrote a utility function (attached) that goes
through the entire document and reports any references to page objects
that are no longer in the main page sequences (i.e. dead references).
Running this function on ‘Transformed.pdf’ produces the following
output:
Dead reference: 303 in 25
Dead reference: 275 in 111
Dead reference: 313 in 322
Dead reference: 313 in 323
Dead reference: 313 in 324
Dead reference: 313 in 325
Dead reference: 313 in 326
Dead reference: 313 in 327
Dead reference: 313 in 328
Dead reference: 313 in 329
Using CosEdit (http://www.pdftron.com/pdfcosedit) we found that the
culprit is that some annotation dictionaries still have a reference to
the page through its “P” entry.
To fix this problem you could either erase optional “P” entry in all
annotations (i.e. annot.GetSDFObj().Erase(“P”)) or update it to point
to the new page (annot.GetSDFObj().Put(“P”, new_page.GetSDFObj())).
Please let me know if this helps.