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

xkrw2x1b  于 2023-05-27  发布在  Python
关注(0)|答案(3)|浏览(304)

如何从PDF内的文本中提取字体颜色?
我已经尝试使用PDFMiner探索LTTextLTChar对象,但似乎这个模块只允许提取字体大小和样式,而不是颜色。

jhiyze9q

jhiyze9q1#

我查看了PDFMiner(未维护)和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和non_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)
vmdwslir

vmdwslir2#

PDFMiner的LTChar对象具有'graphicstate'属性,该属性具有'color'(描边颜色)和'ncolor'(非描边颜色)属性,可用于获取文本颜色信息。下面是工作代码片段(基于其中一个答案中的代码),它输出每个文本行组件的字体信息:

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

with open(sys.argv[1], 'rb') as scr_file:
    for page_layout in extract_pages(scr_file):
        for element in page_layout:
            if isinstance(element, LTTextContainer):
                fontinfo = set()
                for text_line in element:
                    for character in text_line:
                        if isinstance(character, LTChar):
                            fontinfo.add(character.fontname)
                            fontinfo.add(character.size)
                            fontinfo.add(character.graphicstate.scolor)
                            fontinfo.add(character.graphicstate.ncolor)
                print("\n", element.get_text(), fontinfo)
9rnv2umw

9rnv2umw3#

(免责声明:我是pText的作者,本例中使用的库。)
pText允许您注册一个EventListener,每当PDF渲染指令(如渲染文本)被处理时,该EventListener都会收到通知。
收到此指令后,您可以检查图形状态,以确定当前描边/填充颜色是什么。应使用描边颜色呈现文本。
让我们来看看它是如何工作的:

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

可以看到,这个类有一个方法event_occurred,它将在呈现内容时被调用。在我们的例子中,我们只对ChunkOfTextRenderEvent感兴趣。
因此,我们验证(使用isinstanceof),然后将调用委托给另一个方法。
_render_text方法中,我们可以从刚刚呈现的文本中获得我们想要的所有信息。如font_colorfont_size
您可以在GitHub上或使用PyPi获取pText还有很多examples,请查看它们以了解更多有关使用图像的信息。

相关问题