Esempio n. 1
0
def generatePDFFromPDF(fileName,
                       inPage,
                       cropRect,
                       outSize,
                       pageLayout,
                       trim=False,
                       registrationMarks=False,
                       progress=None):
    assert isinstance(inPage, InputPDFPage)
    inReaderPage = inPage.getPyPDF2PageObject()

    overlayPage = None
    if trim or registrationMarks:
        with tempfile.TemporaryDirectory(prefix='pdfXplode-tmpPDF') as d:
            # Print our trimming and registration marks to a temporary
            # PDF so we can merge it with the input PDF.  Sadly,
            # QPrinter has no way to print to an in-memory stream so we
            # have to use a temporary file.
            tmpFileName = os.path.join(d, 'overlay.pdf')

            printer = QPrinter()
            printer.setOutputFormat(QPrinter.PdfFormat)
            printer.setOutputFileName(tmpFileName)
            printer.setPageLayout(pageLayout)
            printOverlayPage(printer, trim, registrationMarks)

            with open(tmpFileName, 'rb') as f:
                overlayPDFBytes = f.read()

        reader = PyPDF2.PdfFileReader(io.BytesIO(overlayPDFBytes))
        overlayPage = reader.getPage(0)

    fullRect = printer.pageLayout().fullRectPoints()
    margin = printer.pageLayout().marginsPoints()

    printableWidth = fullRect.width() - margin.left() - margin.right()
    printableHeight = fullRect.height() - margin.top() - margin.bottom()

    numPagesX = math.ceil(outSize.width() / printableWidth)
    numPagesY = math.ceil(outSize.height() / printableHeight)
    numPages = numPagesX * numPagesY

    outPDF = PyPDF2.PdfFileWriter()

    for y in range(numPagesY):
        for x in range(numPagesX):
            percentComplete = ((numPagesX * y + x) * 100) // (numPages + 1)
            if progress and not progress(percentComplete):
                return

            xt = x * printableWidth
            yt = y * printableHeight

            # PDF coordinates start at the bottom-left but everything
            # else is top-down so flip the Y transform
            yt = outSize.height() - yt - printableHeight

            xform = QTransform()
            xform.translate(margin.left(), margin.bottom())
            xform.translate(-xt, -yt)
            xform.scale(outSize.width() / cropRect.width(),
                        outSize.height() / cropRect.height())
            xform.translate(-cropRect.x(), -cropRect.y())
            assert xform.isAffine()
            ctm = (xform.m11(), xform.m12(), xform.m21(), xform.m22(),
                   xform.m31(), xform.m32())
            page = outPDF.addBlankPage(fullRect.width(), fullRect.height())
            page.mergeTransformedPage(inReaderPage, ctm)

            if overlayPage:
                page.mergePage(overlayPage)

    if progress:
        progress((numPages * 100) // (numPages + 1))

    with open(fileName, 'wb') as f:
        outPDF.write(f)

    if progress:
        progress(100)