Skip to content

Error when rendering shapes to existing pdf #1167

Description

@carlaTV

Please provide all mandatory information!

Describe the bug (mandatory)

When I commit a set of shapes to a blank pdf, the result is as expected. However, when I try to commit them to an existing pdf, they are turned 90 degrees (upside down), rescaled and sometimes the text does not appear anymore.

To Reproduce (mandatory)

Consider an input as "original_document.pdf" (attached), where shapes and text coexist.
original_document.pdf

Fitz can successfully extract the text and the shapes, and when I render them separately it works as expected (see only_shapes.pdf and only_text.pdf).
only_shapes.pdf
only_text.pdf
This is how I generate each file:
TEXT EXTRACTION:

import fitz
import pdfkit

filename = 'original_document.pdf'

doc = fitz.open(filename)
page = doc[0]                    # it has only one page
text = page.get_text("html")
with open('text.html', 'w') as f:
    f.write(text)
pdfkit.from_file('text.html', 'only_text.pdf')

SHAPES EXTRACTION

import fitz

# open original document
doc = fitz.open(path_input+filename)
page = doc[0]                   # it has only one page

outpdf = fitz.open()         # open new document
outpage = outpdf.new_page(width=page.rect.width, height=page.rect.height)         # create new page
shape = outpage.new_shape()  # make a drawing canvas for the output page

paths = page.get_drawings()  # extract existing drawings

for path in paths:
    # ------------------------------------
    # draw each entry of the 'items' list
    # ------------------------------------
    for item in path["items"]:  # these are the draw commands
        if item[0] == "l":  # line
            shape.draw_line(item[1], item[2])
        elif item[0] == "re":  # rectangle
            shape.draw_rect(item[1])
        elif item[0] == "c":  # curve
            shape.draw_bezier(item[1], item[2], item[3], item[4])
        else:
            raise ValueError("unhandled drawing", item)
    # ------------------------------------------------------
    # all items are drawn, now apply the common properties
    # to finish the path
    # ------------------------------------------------------
    shape.finish(
        fill=path["fill"],  # fill color
        color=path["color"],  # line color
        dashes=path["dashes"],  # line dashing
        even_odd=path["even_odd"],  # control color of overlaps
        closePath=path["closePath"],  # whether to connect last and first point
        lineJoin=path["lineJoin"],  # how line joins should look like
        lineCap=max(path["lineCap"]),  # how line ends should look like
        width=path["width"],  # line width
        stroke_opacity=path["opacity"],  # same value for both
        fill_opacity=path["opacity"],  # opacity parameters
        )
# all paths processed - commit the shape to its page
shape.commit()

outpdf.save('only_shapes.pdf')

THE ISSUE: COMMITING SHAPES TO AN EXISTING DOCUMENT
In order to add the extracted shapes to the doument that only contains the shapes (in other words: committing the shapes to only_text.pdf), instead of creating a new document and a new page within it with these lines of code:

outpdf = fitz.open()         # open new document
outpage = outpdf.new_page(width=page.rect.width, height=page.rect.height)         # create new page
shape = outpage.new_shape()  # make a drawing canvas for the output page

I open the document "only_text.pdf" and define its first page as outpage :

outpdf = fitz.open('only_text.pdf')                     # open existing document
outpage = outpdf[0]                                           # define outpage as the first (and only) page
shape = outpage.new_shape()                          # make a drawing canvas for the output page

text_and_shapes__same_file.pdf

It has to be mentioned that if I create a new page to an existing document, it correctly commits the shapes to this new page (however, this is not what I want).
See text_and_shapes__sep_file.pdf

Expected behavior (optional)

What I want is to be able to extract text and shapes from a pdf and generate them in a new document.

Screenshots (optional)

What I want:
image

I am able to generate the shapes in a new page:
image

However, when I try to commit them to an existing document, they appear upside down and rescaled (and in some cases, like this one, the text disappears):
image

I assume that I am doing something wrong when I define outpage as an existing pdf page.

Your configuration (mandatory)

  • Operating system: MacOS Catalina
  • Python 3.6.4
  • PyMuPDF Version: 1.18.14, installed with pip.

For example, the output of print(sys.version, "\n", sys.platform, "\n", fitz.__doc__) would be sufficient (for the first two bullets).
3.6.4 (v3.6.4:d48ecebad5, Dec 18 2017, 21:07:28)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]
darwin

PyMuPDF 1.18.14: Python bindings for the MuPDF 1.18.0 library.
Version date: 2021-06-01 08:11:38.
Built for Python 3.6 on darwin (64-bit).

Additional context (optional)

Thanks a lot!!

Metadata

Metadata

Assignees

Labels

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

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions