allefeld / pytikz

A Python interface to TikZ
GNU General Public License v3.0
63 stars 11 forks source link

'Document' object has no attribute 'loadPage' #4

Closed AjeyDikshit closed 1 year ago

AjeyDikshit commented 1 year ago

Every time, I try to display the Picture() instance in Jupyter notebook, it gives this error.

image

allefeld commented 1 year ago

My guess is that this has to do with an API change in one of the packages I use. I'll look into it.

abdullahkhalids commented 1 year ago

Hey! I just encountered this issue. The issue is that pymupdf (that fitz uses) has changed its api. The changes are documented here https://pymupdf.readthedocs.io/en/latest/znames.html

For the error above, you need to change the _get_SVG and _get_PNG and write_image functions as follows:

  def _get_SVG(self):
        "return SVG data of `Picture`"
        # convert PDF to SVG using PyMuPDF
        doc = fitz.open(self.temp_pdf)
        page = doc.load_page(0)
        svg = page.get_svg_image()
        return svg

    def _get_PNG(self, dpi=None):
        "return PNG data of `Picture`"
        if dpi is None:
            dpi = cfg.display_dpi
        # convert PDF to PNG using PyMuPDF
        zoom = dpi / 72
        doc = fitz.open(self.temp_pdf)
        page = doc.load_page(0)
        pix = page.get_pixmap(matrix=fitz.Matrix(zoom, zoom))
        return pix.tobytes()

    def write_image(self, filename, dpi=None):
        """
        write picture to image file

        The file type is determined from the file extension, and can be PDF,
        PNG, or SVG. For PDF, the file created by LaTeX is copied to
        `filename`. For PNG, the PDF is rendered to a bitmap. If the
        resolution `dpi` is not specified, `cfg.file_dpi` is used. For
        SVG, the PDF is converted to SVG.

        Rendering and conversion are performed by the
        [MuPDF library](https://mupdf.com/) through the Python binding
        [PyMuPDF](https://pymupdf.readthedocs.io/en/latest/).
        """
        if dpi is None:
            dpi = cfg.file_dpi
        self._update()
        # determine extension
        _, ext = os.path.splitext(filename)
        # if a PDF is requested,
        if ext.lower() == '.pdf':
            # just copy the file
            shutil.copyfile(self.temp_pdf, filename)
        elif ext.lower() == '.png':
            # render PDF as PNG using PyMuPDF
            zoom = dpi / 72
            doc = fitz.open(self.temp_pdf)
            page = doc.load_page(0)
            pix = page.get_pixmap(matrix=fitz.Matrix(zoom, zoom), alpha=True)
            pix.save(filename)
        elif ext.lower() == '.svg':
            # convert PDF to SVG using PyMuPDF
            svg = self._get_SVG()
            with open(filename, 'w') as f:
                f.write(svg)
        else:
            raise ValueError(f'format {ext[1:]} is not supported')
allefeld commented 1 year ago

@abdullahkhalids thanks for looking into this! Would you like to do a PR? Otherwise I'll copy your code and commit it myself.

abdullahkhalids commented 1 year ago

Thanks. I have sent in a PR request. Not something I do often, so sorry if any information is missing.

abdullahkhalids commented 1 year ago

Also, can I say thank you so much for this library. I finally don't want to bang my head against my desk when using tikz.

allefeld commented 1 year ago

Great, merged it and appears to work. And I'm glad someone beside myself finds this useful!