使用ReportLab(Python)的PDF文档中的PDF图像

时间:2010-08-10 11:23:32

标签: python image pdf reportlab

我将matplotlib的一些图表保存为pdf格式,因为它似乎提供了更好的质量。如何使用ReportLab将PDF图像包含到PDF文档中?便捷方法Image(filepath)不适用于此格式。

谢谢。

4 个答案:

答案 0 :(得分:3)

根据ReportLab's FAQ,这只适用于ReportLab PLUS:

  

我可以在PDF中使用矢量图形吗?

     

不,开源软件包没有   这个。 PageCatcher(见前面的内容   回答)让你轻松   通过保存合并任何矢量图像   它作为PDF然后完全使用它   就像你想要一个图像文件和报告一样   标记语言接受PDF文件   以及JPG,GIF和PNG。

更新:我暂时没有考虑过这个问题但是on the page of pdfrw它说:

  

pdfrw可以读写PDF文件,也​​可以用来读取PDF文件,然后可以在reportlab中使用。

答案 1 :(得分:2)

您可以将精彩的pdfrw软件包与reportlab一起使用,并使用它将matplotlib图形的文件对象直接传递给可流动的文件:

之前已经回答了,但我想在这里给出一个最小的例子,请看这里:https://stackoverflow.com/a/13870512/4497962

from io import BytesIO
import matplotlib.pyplot as plt
from pdfrw import PdfReader, PdfDict
from pdfrw.buildxobj import pagexobj
from pdfrw.toreportlab import makerl
from reportlab.platypus import Flowable
from reportlab.lib.enums import TA_JUSTIFY,TA_LEFT,TA_CENTER,TA_RIGHT

class PdfImage(Flowable):
    """
    PdfImage wraps the first page from a PDF file as a Flowable
    which can be included into a ReportLab Platypus document.
    Based on the vectorpdf extension in rst2pdf (http://code.google.com/p/rst2pdf/)

    This can be used from the place where you want to return your matplotlib image
    as a Flowable:

        img = BytesIO()

        fig, ax = plt.subplots(figsize=(canvaswidth,canvaswidth))

        ax.plot([1,2,3],[6,5,4],antialiased=True,linewidth=2,color='red',label='a curve')

        fig.savefig(img,format='PDF')

        return(PdfImage(img))

    """

    def __init__(self, filename_or_object, width=None, height=None, kind='direct'):
        # If using StringIO buffer, set pointer to begining
        if hasattr(filename_or_object, 'read'):
            filename_or_object.seek(0)
            #print("read")
        self.page = PdfReader(filename_or_object, decompress=False).pages[0]
        self.xobj = pagexobj(self.page)

        self.imageWidth = width
        self.imageHeight = height
        x1, y1, x2, y2 = self.xobj.BBox

        self._w, self._h = x2 - x1, y2 - y1
        if not self.imageWidth:
            self.imageWidth = self._w
        if not self.imageHeight:
            self.imageHeight = self._h
        self.__ratio = float(self.imageWidth)/self.imageHeight
        if kind in ['direct','absolute'] or width==None or height==None:
            self.drawWidth = width or self.imageWidth
            self.drawHeight = height or self.imageHeight
        elif kind in ['bound','proportional']:
            factor = min(float(width)/self._w,float(height)/self._h)
            self.drawWidth = self._w*factor
            self.drawHeight = self._h*factor

    def wrap(self, availableWidth, availableHeight):
        """
        returns draw- width and height

        convenience function to adapt your image 
        to the available Space that is available
        """
        return self.drawWidth, self.drawHeight

    def drawOn(self, canv, x, y, _sW=0):
        """
        translates Bounding Box and scales the given canvas
        """
        if _sW > 0 and hasattr(self, 'hAlign'):
            a = self.hAlign
            if a in ('CENTER', 'CENTRE', TA_CENTER):
                x += 0.5*_sW
            elif a in ('RIGHT', TA_RIGHT):
                x += _sW
            elif a not in ('LEFT', TA_LEFT):
                raise ValueError("Bad hAlign value " + str(a))

        #xobj_name = makerl(canv._doc, self.xobj)
        xobj_name = makerl(canv, self.xobj)

        xscale = self.drawWidth/self._w
        yscale = self.drawHeight/self._h

        x -= self.xobj.BBox[0] * xscale
        y -= self.xobj.BBox[1] * yscale

        canv.saveState()
        canv.translate(x, y)
        canv.scale(xscale, yscale)
        canv.doForm(xobj_name)
        canv.restoreState()

答案 2 :(得分:1)

您可以使用matplotlib中的 svg 导出并使用svglib python库在reportlab生成的PDF文件中包含矢量图形。 svglib获取svg文件并生成可直接在reportlab中使用的绘图对象。

有关详情,请参阅此问题:Generating PDFs from SVG input

答案 3 :(得分:-4)

使用reportlab.graphics导入renderPDF