Can't change /Contents of annotation

2020-05-06 11:03发布

问题:

I'm trying to change the text in some PDF annotations using iTextSharp. Here is my code:

    void changeAnnotations(string inputPath, string outputPath)
    {
        PdfReader pdfReader = new PdfReader(inputPath);
        PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(outputPath, FileMode.Create));

        //get the PdfDictionary of the 1st page
        PdfDictionary pageDict = pdfReader.GetPageN(1);

        //get annotation array
        PdfArray annotArray = pageDict.GetAsArray(PdfName.ANNOTS);

        //iterate through annotation array
        int size = annotArray.Size;
        for (int i = 0; i < size; i++)
        {

            //get value of /Contents
            PdfDictionary dict = annotArray.GetAsDict(i);
            PdfString contents = dict.GetAsString(PdfName.CONTENTS);

            //check if /Contents key exists
            if (contents != null)
            {

                //set new value
                dict.Put(PdfName.CONTENTS, new PdfString("value has been changed"));
            }
        }
        pdfStamper.Close();
    }

When I open the output file in Adobe Reader, none of the text has changed in any of the annotations. How should I be setting the new value in an annotation?

UPDATE: I've found that the value is being changed in the popup box that appears when I click on the annotation. And in some cases, when I modify this value in the popup box, the change is then applied to the annotation.

回答1:

As the OP clarified in a comment:

This annotation is a FreeText, how do I find and change the text that's displayed in this text box?

Free text annotations allow a number of mechanisms to set the displayed text:

  • A pre-formatted appearance stream, referenced by the N entry in the AP dictionary
  • A rich text string with a default style string given in RC and DS respectively
  • A default appearance string applied to the contents given in DA and Contents respectively

(For details cf. the PDF specification ISO 32000-1 section 12.5.6.6 Free Text Annotations)

If you want to change the text using one of these mechanisms, make sure you remove or adjust the contents of the entries for the other mechanisms; otherwise your change might not be visible or even visible on some viewers but not visible on others.

I can't figure out how to determine if there is an appearance stream. Is that the /AP property? I checked that for one of the annotations and it's a dictionary with a single entry whose value is 28 0 R.

So that one of the annotations indeed comes with an appearance stream. The single entry whose value is 28 0 R presumably has the N name to indicate the normal appearance. 28 0 R is a reference to the indirect object with object number 28 and generation 0.

If you want to change the text content but do not want to deal with the formatting details, you should remove the AP entry.