PDF изображение в PDF документе с использованием ReportLab (Python) - PullRequest
10 голосов
/ 10 августа 2010

Я сохранил некоторые сюжеты из matplotlib в формате pdf, потому что он, кажется, предлагает лучшее качество. Как включить изображение PDF в документ PDF с помощью ReportLab? Удобный метод Image (filepath) не работает для этого формата.

Спасибо.

Ответы [ 4 ]

3 голосов
/ 16 марта 2011

Согласно FAQLabL FAQ это возможно только с ReportLab PLUS:

Можно ли использовать векторную графику в моих PDF-файлах?

Нет, с открытым исходным кодомпакет не делает этого.PageCatcher (см. Предыдущий ответ) позволяет легко включать любое векторное изображение, сохраняя его в формате PDF, а затем используя его точно так же, как и файл изображения, а язык разметки отчетов принимает файлы PDF вместе с JPG, GIF и PNG.

Обновление : я давно не разбирался с этим, но на странице pdfrw написано:

pdfrwможет читать и записывать PDF-файлы, а также может использоваться для чтения в PDF-файлах, которые затем можно использовать в reportlab.

2 голосов
/ 23 января 2017

Вы можете использовать замечательный пакет 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()
0 голосов
/ 02 февраля 2017

Вы можете использовать svg export из matplotlib и использовать библиотеку svglib python для включения векторной графики в файлы PDF, созданные с помощью reportlab. svglib берет svg-файл и создает рисованный объект, который можно напрямую использовать в reportlab.

См. Также этот вопрос для получения более подробной информации: Создание PDF-файлов из SVG-ввода

0 голосов
/ 04 ноября 2010

Использовать из reportlab.graphics import renderPDF

...