如何使用 PDFMiner 在 Python 中提取 PDF 中文本的字体颜色?

How can I extract font color of text within a PDF in Python with PDFMiner?

如何从 PDF 中的文本中提取字体颜色?

我已经尝试使用 PDFMiner 探索 LTTextLTChar 对象,但似乎该模块只允许提取字体大小和样式,而不是颜色。

(免责声明:我是 pText 的作者,本示例中使用的库。)

pText 允许您注册一个 EventListener ,只要处理了 PDF 渲染指令(例如渲染文本)就会收到通知。

收到此指令后,您可以检查图形状态以确定当前 stroke/fill 颜色是什么。文本应使用描边颜色呈现。

让我们来看看它是如何工作的:

with open("input.pdf", "rb") as pdf_file_handle:
    l = ColorSpectrumExtraction()
    doc = PDF.loads(pdf_file_handle, [l])

以上代码打开PDF文档进行(二进制)阅读,调用PDF.loads方法。我们传递的额外参数是 EventListener 实现的数组(在本例中为 1 个元素)。

我们来看看ColorSpectrumExtraction:

class ColorSpectrumExtraction(EventListener):

    def event_occurred(self, event: Event) -> None:
        if isinstance(event, ChunkOfTextRenderEvent):
            self._render_text(event)

    def _render_text(self, event: ChunkOfTextRenderEvent):
        assert event is not None
        c = event.font_color.to_rgb()
        // do something with the font-color

如您所见,此 class 有一个方法 event_occurred,将在呈现内容时调用该方法。在我们的例子中,我们只对 ChunkOfTextRenderEvent.

感兴趣

所以我们验证(使用isinstanceof)然后将调用委托给另一个方法。

在方法_render_text中,我们可以从刚刚呈现的文本中获取我们想要的所有信息。像 font_colorfont_size

您可以在 GitHub, or using PyPi 上获取 pText 还有更多 examples,请查看它们以了解有关处理图像的更多信息。

我查看了 PDFMiner (not maintained) and PDFMiner.Sixth(fork)的所有源代码。 Python 模块都不允许您提取颜色。在两个模块的问题部分中,提取字体颜色是一个常见问题。

我也看了PDFPlumber,它使用了PDFMiner.Sixth。该模块提取字体颜色。提取出来的颜色元素包括字符轮廓stroking_color,和字符轮廓non_stroking_color,字符的填充。我查看了从示例 PDF 中提取的颜色,它们与 RGB 颜色匹配。

import pdfplumber

pdf_file = pdfplumber.open('path_to_pdf')
for p, char in zip(pdf_file.pages, pdf_file.chars):
    words = p.extract_words(keep_blank_chars=True)
    texts = p.extract_text()
    print(f"Page Number: {p.page_number}")
    print(f"Font Name: {char['fontname']}")
    print(f"Font Size: {char['size']}")
    print(f"Stroking Color: {char['stroking_color']}")
    print(f"Non_stroking Color: {char['non_stroking_color']}")
    print(texts.strip())
    print('\n')

未回答的问题是:

如何提取字体颜色并仍然使用 PDFMiner 代码?

下面的代码允许我同时使用 PDFMiner.SixthPDFPlumber 来提取各种元素,例如文本,源 PDF 文件中的字体名称、字体大小、stroking_color 和非_stroking_color。

import pdfplumber

from pdfminer.high_level import extract_pages
from pdfminer.layout import LTTextContainer, LTChar


with open('path_to_pdf', 'rb') as scr_file:
    with pdfplumber.PDF(scr_file) as pdf_file:
        for page_layout, char in zip(extract_pages(scr_file), pdf_file.chars):
            for element in page_layout:
                if isinstance(element, LTTextContainer):
                    for text_line in element:
                        for character in text_line:
                            if isinstance(character, LTChar):
                                print(element.get_text())
                                print(f"Font Name: {character.fontname}")
                                print(f"Font Size: {character.size}")
                                print(f"Stroking Color: {char['stroking_color']}")
                                print(f"Non_stroking Color: {char['non_stroking_color']}")
                                print('\n\n')

更新 03-09-2021

我仍在致力于将这些功能网格化和同步在一起。我检查了它们,它们似乎输出了正确的元素。

import pdfplumber
from pdfminer.high_level import extract_pages
from pdfminer.layout import LTTextContainer, LTChar, LAParams


def extract_character_characteristics(pdf_file):
    number_of_pages = len(list(extract_pages(pdf_file)))
    for page_layout in extract_pages(pdf_file, laparams=LAParams()):
        print(f'Processing Page: {number_of_pages}')
        number_of_pages -= 1
        for element in page_layout:
            if isinstance(element, LTTextContainer):
                for text_line in element:
                    for character in text_line:
                        if isinstance(character, LTChar):
                            if character.get_text() != ' ':
                                print(f"Character: {character.get_text()}")
                                print(f"Font Name: {character.fontname}")
                                print(f"Font Size: {character.size}")
                                print('\n')


def extract_character_colors(pdf_file):
    with pdfplumber.PDF(pdf_file) as file:
        for char in file.chars:
            if char['text'] != ' ':
                print(f"Page Number: {char['page_number']}")
                print(f"Character: {char['text']}")
                print(f"Font Name: {char['fontname']}")
                print(f"Font Size: {char['size']}")
                print(f"Stroking Color: {char['stroking_color']}")
                print(f"Non_stroking Color: {char['non_stroking_color']}")
                print('\n')


with open('test.pdf', 'rb') as scr_file:
    extract_character_characteristics(scr_file)