.net, Itextsharp, how to flatten comments (specifi

2019-07-22 01:37发布

问题:

In short, I'm having issues specifically "flattening" stamp comments in PDF's while using Itextsharp. The effect I'm looking for is identical to what you get when you "print to PDF" from Acrobat (the stamp can no longer be moved/edited/etc. but you can still select any text it might have). Using some very simple Javascript code also seems to work just fine (this.flattenPages).

This problems seems to specifically pertain to stamps, which is the real trick of it. I've successfully used the pdfstamper class to flatten some other kinds of page comments and annotations (e.g. text boxes) using:

   stamper.FormFlattening = True 
   stamper.FreeTextFlattening = True

But this does NOT work for the any stamps I've tried (the default included in Acrobat or user created). The document just comes out on the other end with the same editable stamp. So... any ideas? And please let me know if there's any additional information I can provide. Thanks.

Update: Obviously this is not the same as other annotations. For whatever it's worth, the stamps (specifically) show up as overcontents. How one would go about changing a flag or otherwise merging/flattening it onto the page is something else I can't find documentation for.

回答1:

Thanks to mkl's comment (see above) pointing me in the right direction, I've found a solution. Here's a VERY abridged explanation of the fix:

I downloaded and edited the source code for Itextsharp and re-compiled the .dll with the small changes I needed. There's obviously other routes to this, but this turned out to be the simplest and most elegant solution. It really just requires including a few additional OR statements to the present code. I would like to note that there's probably a reason this isn't currently included in the official library, so buyer beware:

In the PdfStamperImp class, there's a few small edits required to make it flatten stamps and behave exactly as I wanted it to. All changes are made to the FlatFreeTextFields procedure:

if (!(annDic.Get(PdfName.SUBTYPE)). Equals(PdfName.FREETEXT)) 
                    continue;
}

changes to:

if (!(annDic.Get(PdfName.SUBTYPE)).Equals(PdfName.FREETEXT) | (annDic.Get(PdfName.SUBTYPE)).Equals(PdfName.STAMP)) {
                    continue;
}

and

if (PdfName.FREETEXT.Equals(annot.Get(PdfName.SUBTYPE))) {
            annots.Remove(idx);
            --idx;
}

changes to:

if (PdfName.FREETEXT.Equals(annot.Get(PdfName.SUBTYPE)) | PdfName.STAMP.Equals(annot.Get(PdfName.SUBTYPE))) {
           annots.Remove(idx);
           idx -= 1;
}

As you can see, it's not exactly the most complex change in the world. From here, you simply call stamper.freetextflatten = true like normal and it will now work to get the stamps as well. You could also theoretically get rid of these statements altogether and it would (at least attempt) to do this with all the annotations on your page. I suspect that might not be a safe idea, but I can't be sure.