Skip to content

Page.get_images_info() is returning empty array. Need a reliable way to detect non-text PDF pages #5017

Closed

Description

@manikantaaddagatla

Description of the bug

Hi Team,

i have page where

  1. page.get_images_info() is returning empty array whereas pymupdf4llm.to_markdown is giving 2 page blocks with class 'picture'
  2. page.get_text() is returning null.

PFA pdf file.
Thanks of the support.

bug_page1.pdf

How to reproduce the bug

Run below python code

import pymupdf
import pymupdf4llm

input_path = "<path_to_file>"
doc = pymupdf.open(input_path)

for page in doc:
    print(f"text {page.get_text()}")

    image_infos = page.get_image_info(xrefs=True)
    print(f"page number {page.number} image_infos : {image_infos}")

documentText = pymupdf4llm.to_markdown(doc,page_chunks = True)
print(f"document text : {documentText}")

versions:
PyMuPDF 1.27.2.2
pymupdf-layout 1.27.2.2
pymupdf4llm 1.27.2.2

PyMuPDF version

1.27.2.2

Operating system

MacOS

Python version

3.14

Activity

  1. JorjMcKie commented on Jun 10, 2026

    @JorjMcKie
    Collaborator

    This discrepancy as such is no bug.
    If the layout module classifies a page region as "picture" then this does not mean it has found an image there. It might as well be vector graphics which are no images and thus do not show up when you try to extract images!

    What appears to be text on that page in reality are vector graphics that mimic text. Identifying them as "picture" therefore is at least not far from the truth.

    One could argue that mimicked text should be OCR-ed ... and this is indeed what is built into the page analyzer module.
    However: there exists no bullet-proof way to tell apart text mimicry and general vector drawings. Therefore some probability / plausibility checks are used based on image properties of the rendered page (FFT analysis, Sobel gradients, edge energy and more). Our guiding principle here is to avoid unnecessary OCR signals because OCR is a performance hog. If in doubt do not OCR.

    If you run pymupdf4llm.to_markdown(...) with the option force_ocr=True the text will be OCR-ed successfully (assuming at least Tesseract is usable on your machine).

  2. julian-smith-artifex-com commented on Jun 10, 2026

    @julian-smith-artifex-com
    Collaborator

    Also note that page.get_drawings() will return the content.

  3. manikantaaddagatla commented on Jun 11, 2026

    @manikantaaddagatla
    Author

    Hi @JorjMcKie and @julian-smith-artifex-com,

    Thanks for the quick reply. As you mentioned, OCR has been disabled for performance reasons, but that does not solve my issue. I will change title slightly

    My core logic is roughly:

    if hasImage(page):       # in this method, i check page.get_image_infos() and check the image size (to ignore banners)
        use pymupdf4llm.to_markdown(doc, pages=[page.number], ignore_images=True, use_ocr=False)
    else:
        process entire page as image

    From what i understand, my current logic only detects images. I need a way to identify all non-text PDF pages, including pages that use vector graphics to render text-like content.

    so could you please share a code snippet that I can use to reliably detect non-text PDF page?

  4. changed the title [-]Page.get_images_info() is returning empty array[/-] [+]Page.get_images_info() is returning empty array. Need a reliable way to detect non-text PDF pages[/+] on Jun 11, 2026
  5. JorjMcKie commented on Jun 11, 2026

    @JorjMcKie
    Collaborator

    Your "bug" example: is this a non-text page for you?

  6. manikantaaddagatla commented on Jun 11, 2026

    @manikantaaddagatla
    Author

    Please correct me if I am wrong, but page.get_text() is returning an empty string, even though I can see text in the PDF. Based on this behaviour, I am considering this a non-text page.

  7. JorjMcKie commented on Jun 11, 2026

    @JorjMcKie
    Collaborator

    Please correct me if I am wrong, but page.get_text() is returning an empty string, even though I can see text in the PDF. Based on this behaviour, I am considering this a non-text page.

    All right then: simply do if (page.get_text()).isspace(): # no text on page.
    Empty strings and strings only containing white space (include line breaks etc.) count as: "this page has no text".

  8. manikantaaddagatla commented on Jun 11, 2026

    @manikantaaddagatla
    Author

    That would solve for this particular PDF. However, as I mentioned above, my core logic (with a minor correction) needs to be more generic. I need a reliable way to determine whether a page contains images or vector graphics that visually represent text, so that I can process such pages differently from pages containing extractable text.

    I'll correct my non text page definition - page has text (optional) + (images or vector graphics that visually represent text)

  9. JorjMcKie commented on Jun 11, 2026

    @JorjMcKie
    Collaborator

    ... + (images or vector graphics that visually represent text)

    You are visiting the same points again: there is no way to determine this without OCR!

  10. manikantaaddagatla commented on Jun 11, 2026

    @manikantaaddagatla
    Author

    Understood. Can I use an approach like this?

    If a page contains any block that occupies a significant portion of the page and is not classified as text or table, can I treat the entire page as an image page and process it?

    My apologies for prolonging this discussion, but this is very critical for us because we do not want to miss any extractable data from a page.

  11. JorjMcKie commented on Jun 11, 2026

    @JorjMcKie
    Collaborator

    ... we do not want to miss any extractable data ...

    If this is so you have only two options left:

    • Rely on the page analyzer of pymupdf4llm. It checks a page's characteristics and returns a probability value for "this page needs OCR". Mind you: "probability"! False positives and false negatives will occur.
      • It is inevitable to accept some error margin if you want to avoid executing OCR on every page.
      • Your example page does not meet the criteria "needs OCR". Therefore the vector text mimicry is interpreted as "picture".
    • Do not trust the page analyzer. Do this by using force_ocr=True. The analyzer will not be executed and every page will be sent to an OCR engine.

    The available OCR plugins for Tesseract and RapidOCR all perform what I call "hybrid OCR". They respect existing page text and only OCR the "rest" of the page. This works whether or not you are using the page analyzer. The result is a mixture of extractable text and text added by the OCR engine.
    The modified page is then sent to the Layout module which makes sense of all that.

  12. JorjMcKie commented on Jun 11, 2026

    @JorjMcKie
    Collaborator

    For clarity, I am going to move this post to the "Discussions" tab.

  13. locked and limited conversation to collaborators on Jun 11, 2026
  14. converted this issue into a discussion #5021 on Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    not a bugnot a bug / user error / unable to reproduce

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions