Adding PDF Annotations

Note

By default, some annotations might be invisible, for example polylines, as the default color is “transparent”.

To circumvent this, make sure to add the /C entry to the annotation, being an array and each array value being in the range 0.0 to 1.0:

  • With one element, a grayscale value.

  • With three elements, a RGB definition.

  • With four elements, a CMYK definition.

Attachments

from pypdf import PdfWriter

writer = PdfWriter()
writer.add_blank_page(width=200, height=200)

data = b"any bytes - typically read from a file"
writer.add_attachment("smile.png", data)

writer.write("out-attachment.pdf")

Free Text

If you want to add text in a box like this

you can use FreeText:

from pypdf import PdfReader, PdfWriter
from pypdf.annotations import FreeText

# Fill the writer with the pages you want
reader = PdfReader("crazyones.pdf")
page = reader.pages[0]
writer = PdfWriter()
writer.add_page(page)

# Create the annotation and add it
annotation = FreeText(
    text="Hello World\nThis is the second line!",
    rect=(50, 550, 200, 650),
    font="Arial",
    bold=True,
    italic=True,
    font_size="20pt",
    font_color="00ff00",
    border_color="0000ff",
    background_color="cdcdcd",
)

# Set annotation flags to 4 for printable annotations.
# See "AnnotationFlag" for other options, e.g. hidden etc.
annotation.flags = 4

writer.add_annotation(page_number=0, annotation=annotation)

# Write the annotated file to disk
writer.write("out-free-text.pdf")

Text

A text annotation looks like this:

Line

If you want to add a line like this:

you can use Line:

from pypdf import PdfReader, PdfWriter
from pypdf.annotations import Line

reader = PdfReader("crazyones.pdf")
page = reader.pages[0]
writer = PdfWriter()
writer.add_page(page)

# Add the line
annotation = Line(
    text="Hello World\nLine2",
    rect=(50, 550, 200, 650),
    p1=(50, 550),
    p2=(200, 650),
)
writer.add_annotation(page_number=0, annotation=annotation)

# Write the annotated file to disk
writer.write("out-line.pdf")

PolyLine

If you want to add a line like this:

you can use PolyLine:

from pypdf import PdfReader, PdfWriter
from pypdf.annotations import PolyLine
from pypdf.generic import ArrayObject, FloatObject, NameObject

reader = PdfReader("crazyones.pdf")
page = reader.pages[0]
writer = PdfWriter()
writer.add_page(page)

# Add the polyline
# By default, the line will be transparent. Set an explicit color.
annotation = PolyLine(
    vertices=[(50, 550), (200, 650), (70, 750), (50, 700)],
)
annotation[NameObject("/C")] = ArrayObject(
    [FloatObject(0.9), FloatObject(0.1), FloatObject(0)]
)
writer.add_annotation(page_number=0, annotation=annotation)

# Write the annotated file to disk
writer.write("out-polyline.pdf")

Rectangle

If you want to add a rectangle like this:

you can use Rectangle:

from pypdf import PdfReader, PdfWriter
from pypdf.annotations import Rectangle

reader = PdfReader("crazyones.pdf")
page = reader.pages[0]
writer = PdfWriter()
writer.add_page(page)

# Add the rectangle
annotation = Rectangle(
    rect=(50, 550, 200, 650),
)
writer.add_annotation(page_number=0, annotation=annotation)

# Write the annotated file to disk
writer.write("out-rectangle.pdf")

If you want the rectangle to be filled, use the interiour_color="ff0000" parameter.

This method uses the “square” annotation type of the PDF format.

Ellipse

If you want to add a circle like this:

you can use Ellipse:

from pypdf import PdfReader, PdfWriter
from pypdf.annotations import Ellipse

reader = PdfReader("crazyones.pdf")
page = reader.pages[0]
writer = PdfWriter()
writer.add_page(page)

# Add the rectangle
annotation = Ellipse(
    rect=(50, 550, 200, 650),
)
writer.add_annotation(page_number=0, annotation=annotation)

# Write the annotated file to disk
writer.write("out-ellipse.pdf")

Polygon

If you want to add a polygon like this:

you can use Polygon:

from pypdf import PdfReader, PdfWriter
from pypdf.annotations import Polygon

reader = PdfReader("crazyones.pdf")
page = reader.pages[0]
writer = PdfWriter()
writer.add_page(page)

# Add the line
annotation = Polygon(
    vertices=[(50, 550), (200, 650), (70, 750), (50, 700)],
)
writer.add_annotation(page_number=0, annotation=annotation)

# Write the annotated file to disk
writer.write("out-polygon.pdf")

Text Markup Annotations

Text markup annotations refer to a specific piece of text within the document.

These are a bit more complicated as you need to know exactly where the text is, the so-called “Quad points”.

Highlighting

If you want to highlight text like this:

you can use Highlight:

from pypdf import PdfReader, PdfWriter
from pypdf.annotations import Highlight
from pypdf.generic import ArrayObject, FloatObject

reader = PdfReader("crazyones.pdf")
page = reader.pages[0]
writer = PdfWriter()
writer.add_page(page)

rect = (50, 550, 200, 650)
quad_points = [rect[0], rect[1], rect[2], rect[1], rect[0], rect[3], rect[2], rect[3]]

# Add the highlight
annotation = Highlight(
    rect=rect,
    quad_points=ArrayObject([FloatObject(quad_point) for quad_point in quad_points]),
)
writer.add_annotation(page_number=0, annotation=annotation)

# Write the annotated file to disk
writer.write("out-highlight.pdf")