我正在嘗試使用 PyMuPDF 將 PDF 檔案中每個單詞的部分加粗。
因此,例如,帶有字串“有很多餡餅”的檔案將導致“有很多餡餅”
我已經看到您可以使用Page.get_textpage().extractWORDS()它來提取各種單詞的元組。但是,我不確定如何將它們的部分加粗。
我曾想過也許你可以擦除它們然后重新撰寫它們,但我不確定 PyMuPDF 是否可以擦除單詞。
uj5u.com熱心網友回復:
看起來 PyMuPDF

我敢打賭,通過在原始(可能仍被編輯)文本之上創建新文本,效果將是完整的,但我現在已經沒有時間去嘗試了。
import fitz
from fitz import Document, Page
from fitz import Matrix, Point, Rect
Normal_style = dict(fontname="helv", fontsize=24)
Bold_style = dict(fontname="hebo", fontsize=24)
RawDictChar = dict # See "Character Dictionary for extractRAWDICT()" in PyMuPDF docs
CharSegment = list[RawDictChar]
def main():
doc: Document = fitz.open()
page: Page = doc.new_page()
page.insert_text(Point(50, 72), "A number of words and things on line 1", **Normal_style)
page.insert_text(Point(50, 144), "A number of words on line 2", **Normal_style)
page.insert_text(Point(50, 216), "Line 3", **Normal_style)
page_to_image(page, "page-orig.png")
char_segments = get_char_segments(page)
apply_segment_redactions(page, char_segments)
page_to_image(page, "page-edit.png")
def get_char_segments(page: Page, num_chars: int = 3) -> list[CharSegment]:
"""
Breaks a page down in groups ("segments") of individual characters, and returns a list of these "character segments".
Each character segment is at most `num_chars` long and will be the first number of characters of a word (delimited by a space).
"""
char_segments: list[CharSegment] = []
rawdict = page.get_text("rawdict")
for block in rawdict["blocks"]:
if block["type"] == 1:
continue # skip "image" block
for line in block["lines"]:
for span in line["spans"]:
chars = span["chars"]
word_chars = []
for char in chars:
# Break on "space"
if char["c"] == " ":
char_segments.append(word_chars[:num_chars])
word_chars = []
continue
word_chars.append(char)
# Get any end-of-line chars
if word_chars:
char_segments.append(word_chars[:num_chars])
return char_segments
def apply_segment_redactions(page: Page, char_segments: list[CharSegment]):
"""Turns each character segment into a redaction annotation, applying the same characters but now in a boldened font."""
M_shift_down = Matrix(1, 1).pretranslate(0, 2.5) # try to compensate for redactions being vertically centered
for char_segment in char_segments:
first_cs = char_segment[0]
# Build up replacement/redaction text
highlight_txt = first_cs["c"]
# Build up "super rect" of redaction area through rectangle unions of each subsequent char in segment
highlight_rect: Rect = Rect(*first_cs["bbox"])
for cs in char_segment[1:]:
highlight_rect = highlight_rect | Rect(*cs["bbox"])
highlight_txt = cs["c"]
highlight_rect.transform(M_shift_down)
page.add_redact_annot(highlight_rect, text=highlight_txt, fill=False, **Bold_style)
page.apply_redactions(images=fitz.PDF_REDACT_IMAGE_NONE)
def page_to_image(page: Page, fname):
"""Helper to visualize the original and redacted/highlighted."""
Zoom_x = 2.0 # horizontal zoom
Zoom_y = 2.0 # vertical zoom
Z_matrix = fitz.Matrix(Zoom_x, Zoom_y) # zoom factor 2 in each dimension
pix = page.get_pixmap(matrix=Z_matrix) # use 'mat' instead of the identity matrix
pix.save(fname) # store image as a PNG
if __name__ == "__main__":
main()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/481829.html
下一篇:將PDF資料提取到資料框中
