Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding text annotations to a page #305

Open
nicholasbailey87 opened this issue Feb 10, 2022 · 6 comments
Open

Adding text annotations to a page #305

nicholasbailey87 opened this issue Feb 10, 2022 · 6 comments

Comments

@nicholasbailey87
Copy link

Thanks so much for the excellent library. I'd like to add "sticky note" text annotations to a PDF page and have been trying to work out how to do it all day. I've tried a million variations along the theme shown below.

Is there a way to do this with pikepdf at the moment, and if so can you please give me a hint about the basic pattern? Thank you for your help! If I can contribute in any way (writing documentation for the correct approach, making a pull request with some utility functions for accomplishing this, etc.) please let me know.

import pikepdf

example = pikepdf.Pdf.open('samples.pdf')

page = example.pages[0]

page_ref = f"{page_object.objgen[0]} {page_object.objgen[1]} R"

note_dict = {
    "/Type": "/Annot",
    "/Subtype": "/Text",
    "/Rect": [100, 100, 125, 125],
    "/C": [0.97, 0.98, 0.31], # yellow
    "/Contents": "Test comment",
    "/P": page_ref,
    "/Name": "Help",
    "/T": "Joe Bloggs"
}

new_annotation = pikepdf.Annotation(pikepdf.Dictionary(note_dict))

page.Annots.append(new_annotation)

example.save('../samples/output.pdf')

example.close()
@jbarlow83
Copy link
Member

I believe you need page_ref = page.obj

@nicholasbailey87
Copy link
Author

Thank you so much for your quick response! I've made the change you suggested. My code is now exactly as shown below.

I'm running it on mariner_from_word.pdf and the intended comment is not appearing on the first page. Also, if I delete the comment that already exists on the first page (so that there are no annotations on that page to begin with) I get AttributeError: /Annots from page.Annots.append(new_annotation.obj).

Maybe I need more stuff in my note_dict? I haven't specified an appearance dictionary for example. The other comment on the same page has a pop-up annotation, which I also haven't made.

import pikepdf

example = pikepdf.Pdf.open('../samples/mariner_from_word.pdf')

page = example.pages[0]

page_ref = page.obj

note_dict = {
    "/Type": "/Annot",
    "/Subtype": "/Text",
    "/Rect": [100., 100., 125., 125.],
    "/Contents": "Test comment",
    "/P": page_ref,
    "/C": (0.97, 0.98, 0.31),
    "/Name": "Help",
    "/T": "Joe Bloggs"
}

new_annotation = pikepdf.Annotation(pikepdf.Dictionary(note_dict))

page.Annots.append(new_annotation.obj)

example.save('../samples/output.pdf')

example.close()

@jbarlow83
Copy link
Member

I think you may need page.Annots = Array() to create the empty array first, before appending to it.

@nicholasbailey87
Copy link
Author

Adding

if not "/Annots" in page:
    page["/Annots"] = pikepdf.Array()

avoids the AttributeError: /Annots when trying to append an annotation to a page with no pre-existing annotations - thanks for that. However I still have the main, original problem that no annotation appears in the document.

@jbarlow83
Copy link
Member

You'll have to excuse me, I'm ridiculously busy with regular work and can't dig into issues right now.

Maybe have a look at https://pypi.org/project/pikepdf-annots/ (a third party annotations package) to see if there's a coding pattern in there you can follow.

@PeterSlezak
Copy link

I had a similar problem where I wanted to add a link annotation which is very similar to the above problem. I made it work so if anyone is interested, the below code adds the text annotation "sticky note" that @nicholasbailey87 wanted (annotation was visible on the first page when I opened the output file in adobe acrobat).

import pikepdf

example = pikepdf.Pdf.open('../samples/mariner_from_word.pdf')
page = example.pages[0]
page_ref = page.obj

if not "/Annots" in page:
    page["/Annots"] = pikepdf.Array()

note_dict = {
    "/Type": pikepdf.Name.Annot,
    "/Subtype": pikepdf.Name.Text,
    "/Rect": [100., 100., 125., 125.],
    "/Contents": "Test comment",
    "/P": page_ref,
    "/C": (0.97, 0.98, 0.31),
    "/Name": "Help",
    "/T": "Joe Bloggs"
}

new_annotation = pikepdf.Annotation(pikepdf.Dictionary(note_dict))
page.Annots.append(new_annotation.obj)
example.save('../samples/output.pdf')
example.close()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants