如何更改 pdf 文档中内嵌文本/自由文本注释的边框和字体颜色?

问题描述 投票:0回答:1

我正在编写一个 python 脚本来更改使用 okular 插入 pdf 文档的文本颜色和内联注释边框。

此脚本似乎不是仅更改文本和边框,而是将整个注释更改为红色(而是显示完整填充的红色矩形)。

这完全受支持吗?我意识到 pdf 格式有多么复杂,但我希望这个简单的更改不需要任何不寻常的东西。

由 okular 生成的 pdf 中的内联文本注释示例:

11533    229·13·obj␍␊
11534    <</Length·293·/Subtype·/Form·/BBox·[0·0·232.7894972067·28.173484252·]·/Resources·<</Font·<</popplerfont·227·0·>>·>>·>>·stream␍␊
11535    q␊
11536    []·0·d␊
11537    2.00·w␊
11538    0.00000·0.00000·0.00000·RG11539    1.00·1.00·230.79·26.17·re␊
11540    0.21569·0.18824·1.00000·rg␊
11541    B11542    4.00·4.00·224.79·20.17·re·W·n11543    0.00000·0.00000·0.00000·rg␊
11544    BT·1·0·0·1·4.00·24.17·Tm11545    /popplerfont·10.00·Tf11546    0.00·-10.00·Td11547    (\000e\000r\000g\000r\000g\000h\000r\000e\000h\000r\000h\000e\000h)·Tj11548    ET·Q11549    ␍␊
11550    endstream␍␊
11551    ␍␊
11552    endobj␍␊
11553    230·0·obj␍␊
11554    <</Type·/Annot·/Rect·[505.4857653631·525.0882627953·507.5172614261·534.4675688976·]·/Subtype·/FreeText·/DA·(/popplerfont·10.00·Tf\n)·/M·(D:20241117102025Z␀································)·/<feff00750073006500720031>·/Contents·<feff>·/NM·(okular-{a598c121-968e-4134-8fa3-b6d17caa86f2})·/CreationDate·(D:20241117102025Z␀································)·/F·20·/C·[0.2156862766·0.1882352978·1·]·/CA·1·/Border·[0·0·2·]·/Q·0·/IT·/FreeText·/P·2·0·R·/AP·<</N·231·0·R·>>·/AS·/>>·␍␊
11555    endobj␍␊
11556    231·0·obj␍␊
11557    <</Length·222·/Subtype·/Form·/BBox·[0·0·2.031496063·9.3793061024·]·/Resources·<</Font·<</popplerfont·227·0·>>·>>·>>·stream␍␊
11558    q␊
11559    []·0·d␊
11560    2.00·w␊
11561    0.00000·0.00000·0.00000·RG11562    1.00·1.00·0.03·7.38·re␊
11563    0.21569·0.18824·1.00000·rg␊
11564    B11565    4.00·4.00·-5.97·1.38·re·W·n11566    0.00000·0.00000·0.00000·rg␊
11567    BT·1·0·0·1·4.00·5.38·Tm11568    /popplerfont·10.00·Tf11569    0.00·-10.00·Td11570    ()·Tj11571    ET·Q11572    ␍␊
11573    endstream␍␊
11574    ␍␊
11575    endobj␍␊
11576    xref␍␊

这里转换为qpdf格式:

40687    0183013890·00000·n·␊
40688    0185638157·00000·n·␊
40689    trailer·<<40690    ··/Info·2·0·R40691    ··/Root·1·0·R40692    ··/Size·37240693    ··/ID·[<fa440df8ed780aedfcf5266a1bfed4ad><fa440df8ed780aedfcf5266a1bfed4ad>]␊
40694    >>40695    startxref␊
40696    18563818340697    %%EOF40698    1·0·obj␍␊
40699    <</Pages·3·0·R·/Type·/Catalog·/AcroForm·373·0·R·>>·␍␊
40700    endobj␍␊
40701    4·0·obj␍␊
40702    <</Contents·68·0·R·/MediaBox·[0·0·595.276·841.89·]·/Parent·3·0·R·/Resources·<</Font·<</F4·70·0·R·/F5·71·0·R·/F6·72·0·R·>>·/ProcSet·73·0·R·/XObject·<</Im3·74·0·R·/Im7·76·0·R·>>·>>·/Type·/Page·/Annots·378·0·R·>>·␍␊
40703    endobj␍␊
40704    372·0·obj␍␊
40705    <</Type·/Annot·/Rect·[142.1173581129·531.1166868381·347.6343759828·552.3443721634·]·/Subtype·/FreeText·/DA·(/popplerfont·10.00·Tf\n)·/M·(D:20241117100201Z␀································)·/<feff00750073006500720031>·/Contents·<feff00750069006500620072006700730075006b0067006200730073006b00650075>·/NM·(okular-{c67d430b-37dd-4ba6-85c6-45a45db4e512})·/CreationDate·(D:20241117100143Z␀································)·/F·20·/C·[0.2156862766·0.1882352978·1·]·/CA·1·/Border·[0·0·2·]·/Q·0·/IT·/FreeText·/P·4·0·R·/AP·<</N·379·16·R·>>·/AS·/>>·␍␊
40706    endobj␍␊
40707    373·0·obj␍␊
40708    <</Fields·[]·/DR·<</Font·<</popplerfont·377·0·>>·>>·>>·␍␊
40709    endobj␍␊
40710    374·0·obj␍␊
40711    <</Length·210957·/Filter·/FlateDecode·>>·stream␍␊
#!/usr/bin/env python3

import sys
import pikepdf
from pikepdf import Name
import re

def change_annotation_font_and_border_to_red(input_path):
    output_path = input_path.replace(".pdf", "-output.pdf")

    # Open the PDF file
    with pikepdf.open(input_path) as pdf:
        for page_number, page in enumerate(pdf.pages, start=1):
            # Check if the page has annotations
            if "/Annots" in page:
                print(f"Page {page_number} contains annotations:")
                # Iterate over each annotation in the /Annots array
                for annot in page["/Annots"]:
                    print(f"  - Annotation detected: {annot}")

                    # Set the border color to red (RGB)
                    annot[Name("/C")] = pikepdf.Array([1, 0, 0])  # RGB for red border

                    # Update the default appearance string (/DA) to set text color to red
                    if "/DA" in annot:
                        da_str = str(annot[Name("/DA")])
                        print(f"    Original /DA: {da_str}")
                        # Remove any existing color settings in the DA string
                        da_str = re.sub(r"(\d+\.?\d*\s){1,3}[rg]", "", da_str)
                        # Append red color setting for text color
                        da_str = da_str.strip() + " 1 0 0 rg"
                        annot[Name("/DA")] = da_str
                        print(f"    Updated /DA: {annot[Name('/DA')]}")

                    # Remove the appearance stream to apply changes if present
                    if "/AP" in annot:
                        del annot[Name("/AP")]
                        print("    Removed /AP to force appearance regeneration")

        # Save the modified PDF with '-output.pdf' suffix
        pdf.save(output_path)
        print(f"Font and border color changed to red. Saved as: {output_path}")

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python change_annotation_font_and_border_to_red.py <input-pdf-path>")
    else:
        input_path = sys.argv[1]
        change_annotation_font_and_border_to_red(input_path)
python pdf pdf-generation poppler pikepdf
1个回答
0
投票

您可以使用 Cpdf 来回注释。第一:

cpdf -list-annotations-json in.pdf > out.json

这将创建一个带有注释(以及任何关联对象)的 JSON 文件。现在,根据需要编辑 JSON。然后,我们可以重新应用它们:

cpdf -remove-annotations in.pdf AND -set-annotations-json out.json -o out.pdf

更多详细信息请参阅手册第 10 章。

© www.soinside.com 2019 - 2024. All rights reserved.