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)