-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Tutorials or better demos to manipulate annotations #107
Comments
Thanks for the feedback. I'm currently working on better documentation for PyPDF2, and I intend for it to feature plenty of examples/demos that might answer questions like yours |
Hi, just want to follow up on this issue. Are there demos/examples for adding annotations? |
Here is an example for creating a highlight: @mstamy2 are you interested in adding methods for highlights? I can provide a pull request. |
Tried to add a new method in pdf.py def hex_to_rgb(value):
return tuple(int(value[i:i+2], 16)/255.0 for i in (0, 2 ,4))
and a method in PdfFileWriter class
def addFreeTextAnno(self, pagenum, txt, rect, font="Helvetica", bold=False,
italic=False, fontSize="14pt", fontColor="ff0000",
borderColor="ff0000", bgColor="ffffff"):
'''
Helvetica
Times New Roman
Courier
bold italic
\r return code
frtxt = DictionaryObject()
frtxt.update({
NameObject('/Type'): NameObject('/Annot'),
NameObject('/Subtype'): NameObject('/FreeText'),
NameObject('/P'): pageLink,
NameObject('/Rect'): RectangleObject(rect),
NameObject('/Contents'): TextStringObject(txt),
#font size color
NameObject('/DS'): TextStringObject("font: bold italic Times New Roman 20pt;color:#ff0000"),
#border color
NameObject('/DA'): TextStringObject("1 0 0 rg "),
#background color
NameObject('/C'): ArrayObject([FloatObject(1), FloatObject(1), FloatObject(1)])
})
'''
pageLink = self.getObject(self._pages)['/Kids'][pagenum]
pageRef = self.getObject(pageLink)
fontStr = "font: "
if bold == True : fontStr = fontStr + "bold "
if italic == True : fontStr = fontStr + "italic "
fontStr = fontStr + font + " " + fontSize
fontStr = fontStr + ";text-align:left;color:#" + fontColor
bgColorStr = ""
for st in hex_to_rgb(borderColor):
bgColorStr = bgColorStr + str(st) + " "
bgColorStr = bgColorStr + "rg"
frtxt = DictionaryObject()
frtxt.update({
NameObject('/Type'): NameObject('/Annot'),
NameObject('/Subtype'): NameObject('/FreeText'),
NameObject('/P'): pageLink,
NameObject('/Rect'): RectangleObject(rect),
NameObject('/Contents'): TextStringObject(txt),
#font size color
NameObject('/DS'): TextStringObject(fontStr),
#border color
NameObject('/DA'): TextStringObject(bgColorStr),
#background color
NameObject('/C'): ArrayObject([FloatObject(n) for n in hex_to_rgb(bgColor)])
})
lnkRef = self._addObject(frtxt)
if "/Annots" in pageRef:
pageRef['/Annots'].append(lnkRef)
else:
pageRef[NameObject('/Annots')] = ArrayObject([lnkRef])
from PyPDF2 import PdfFileReader, PdfFileWriter and following is how to call that method. def main():
output = PdfFileWriter()
input1 = PdfFileReader(file("aaa.pdf", "rb"))
numPages = input1.getNumPages()
for index in range(0, numPages):
pageObj = input1.getPage(index)
output.addPage(pageObj)
output.addFreeTextAnno(index, "My Free Text Annotate", [100,100,350,150],
bold=True, italic=True, fontSize="20pt", fontColor="ffffff", borderColor="ffaa00",
bgColor="000000", font="Times")
annot = pageObj["/Annots"][0].getObject()
annot1 = pageObj["/Annots"][1].getObject()
print annot
print annot1
output.write(open("xx.pdf", 'wb')) |
And @snakemicro? Did it work? |
Hoping someone can offer some assistance on font size/style. I'm trying to detect when a value is too long for a field I've got & adjust the font size, but the font doesn't change. # Add data to a page
page = pdf_writer.getPage(0)
pdf_writer.updatePageFormFieldValues(page, data_dict)
for j in range(0, len(page['/Annots'])):
writer_annot = page['/Annots'][j].getObject()
writer_annot.update({
NameObject("/DS"): TextStringObject(
"font: 12.0pt; color:#E52237"
)
}) |
We might also want to add a PyPDF answer to https://stackoverflow.com/q/47497309/562769 |
I've just added some basic examples. Feel free to add more by creating PRs :-) |
The demo is here: https://pypdf2.readthedocs.io/en/latest/user/adding-pdf-annotations.html What I miss:
|
Full credit to the GitHub user snakemicro: #107 (comment) Co-authored-by: snakemicro
@snakemicro I would add it #981 :-) I just want to wait for some feedback. |
Full credit to the GitHub user snakemicro: #107 (comment) Co-authored-by: snakemicro
Full credit to the GitHub user snakemicro: #107 (comment) Co-authored-by: snakemicro
…ionBuilder (#1120) * Add `page.annotations` (getter and setter) * Add `writer.add_annotation(page_number, annotation_dictionary)` * Add AnnotationBuilder to generate the `annotation_dictionary` for the different subtypes of annotations. Similarly, we could have an AnnotationsParser. See #107 Closes #981
@ubuntuslave @snakemicro I've started working on improving the situation in #1198 . Somehow the popup doesn't show... your help would be very appreciated 🙏 |
Number of files with at least one annotations in my big dataset: ✔️ /Link: 2694x |
* Annotation module: pypdf/generic/_annotations.py ➔ pypdf/annotation.py * Create abstract base class AnnotationDictionary * Create annotation classes: Text, FreeText * DOC: Remove AnnotationBuilder from the docs, use AnnotationDictionary classes directly See #107 See #1741 The annotationBuilder design pattern discussion
* Annotation module: pypdf/generic/_annotations.py ➔ pypdf/annotation.py * Create abstract base class AnnotationDictionary * Create annotation classes: Text, FreeText * DOC: Remove AnnotationBuilder from the docs, use AnnotationDictionary classes directly See #107 See #1741 The annotationBuilder design pattern discussion
The goal of this PR is to create a more intuitive interface for creating annotations. The AnnotationBuild gets deprecated in favor of several annotation classes, e.g. ```python # old from pypdf.generic import AnnotationBuilder annotation = AnnotationBuilder.free_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", ) # new from pypdf.annotations import FreeText 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", ) ``` * `pypdf/generic/_annotations.py` ➔ `pypdf/annotations/` * Create abstract base class AnnotationDictionary * Create abstract base class MarkupAnnotation which inherits from AnnotationDictionary. Most annotations are MarkupAnnotations. * Deprecated AnnotationBuilder * Ensure the AnnotationBuilder is not used in the docs Closes #107
edit by Martin to show the current state:
Number of files with at least one annotations in my big dataset:
✔️ /Link: 2694x
❌ /Widget: 431x - #1207
✔️ /Popup: 189x - #1198 - now #1665
✔️ /FreeText: 85x
✔️ /Text: 77x
✔️ /Square: 47x - #1388
/Stamp: 40x
✔️ /Line: 22x
/DGAP:RedaxBox: 3x
✔️ /Circle: 2x - #1556
/FileAttachment: 2x - don' confuse it with
/EmbeddedFiles
/Ink: 1x - https://pyfpdf.github.io/fpdf2/Annotations.html#ink-annotations
/Caret: 1x
✔️ /Polygon - #1557
✔️ /PolyLine - see #1726
Text markup annotations:
✔️ /Highlight: 22x - https://stackoverflow.com/q/9099497/562769 - see #1740
/StrikeOut: 2x
/Underline: 2x
Original post:
I'm trying to understand how PyPDF2 works with existing annotation objects, such as highlights, and Popups. The demos provided don't show how to _add_ new
DictionaryObjects
to the current list of annotations. I believe my problem resides around not having a way to obtain (find out)idnum
for the new object that it's needed by its parent's to refer to. Here is what I've been doing so far... (To be honest, I gave up looking at the code insidepdf.py
andgeneric.py
because it's taking too long at the moment)P.S: My motivation for this little script is to give it to users of docear since mind-mapping of highlights requires retroactively adding missing popups to highlight annotations (in adobe acrobat) like the proprietary program done by this guy.
The text was updated successfully, but these errors were encountered: