def solve_problems(pdf_file, pages, student_ids, problems, solve, copies_per_student): if solve < 0.01: # nothing to solve return with NamedTemporaryFile() as sol_file: pdf = canvas.Canvas(sol_file.name, pagesize=A4) for id, number_of_copies in zip(student_ids, copies_per_student): for _ in range(number_of_copies): generate_solution(pdf, pages, id, [p for p in problems if random.random() < solve]) if pages % 2 == 1: # for an odd number of pages, zesje adds a blank page at the end pdf.showPage() pdf.save() exam_pdf = PdfReader(pdf_file) overlay_pdf = PdfReader(sol_file) for page_idx, exam_page in enumerate(exam_pdf.pages): overlay_merge = PageMerge().add(overlay_pdf.pages[page_idx])[0] exam_merge = PageMerge(exam_page).add(overlay_merge) exam_merge.render() PdfWriter(pdf_file.name, trailer=exam_pdf).write()
def makeA3(ipath, opath, onesided=False): """Take the first 4 (A4) pages of the input file and place them in "booklet" order on an A3 sheet (double-sided, short-side join). If <onesided> is <True>, or there are only two pages in the input file, place the first two (A4) pages on one side of an A3 sheet, the first page on the right-hand side. Note that the input pages do not have to be A4, the output will simply be twice as wide (as the first page). All input pages should have the same size. """ ipages = PdfReader(ipath).pages # Make sure we have an even number of pages if len(ipages) & 1: ipages.append(None) fpage = PageMerge() fpage.add(ipages[0]) width = fpage[0].w opages = [] if onesided or len(ipages) == 2: p4 = ipages[1] else: p4 = ipages[3] bpage = PageMerge() bpage.add(ipages[1]) bpage.add(ipages[2], prepend=True) bpage[0].x = width opages.append(bpage.render()) if p4: fpage.add(p4) fpage[0].x = width opages.insert(0, fpage.render()) PdfWriter().addpages(opages).write(opath)
def resize(outpages: List, output_size: List[int]) -> List: current_size = get_media_box_size(outpages) o = list(outpages) # rotate output_size if outpages would fit better out_ratio = output_size[0] / output_size[1] cur_ratio = current_size[0] / current_size[1] if out_ratio > 1 and cur_ratio <= 1 or out_ratio <= 1 and cur_ratio > 1: output_size = list(reversed(output_size)) scale, x_margin, y_margin = calculate_margins(output_size, current_size) for idx, page in enumerate(outpages): page = PageMerge().add(page) # scale page page[0].scale(scale) page[0].x += x_margin page[0].y += y_margin # set new mediabox size page.mbox = [0, 0] + output_size # replace original with resized page o[idx] = page.render() return o
def get_single_side_quire_page(pages): number_of_pages = len(pages) assert number_of_pages == round(QUIRE_SIZE / 2) half_index = round(number_of_pages / 2) rotate_all(180, pages[half_index:]) result = PageMerge() + (x for x in pages if x is not None) width = result[0].w height = result[0].h for i in range(half_index): dx = i * width dy = height result[i].x += dx result[i].y += dy for i in range(half_index, number_of_pages): dx = (i - half_index) * width dy = 0 result[i].x += dx result[i].y += dy return result.render()
def adjust(page, margin=36, scale=4.8): info = PageMerge().add(page) x1, y1, x2, y2 = info.xobj_box viewrect = (margin, margin, x2 - x1 - 2 * margin, y2 - y1 - 2 * margin) page = PageMerge().add(page, viewrect=viewrect) page[0].scale(scale) return page.render()
def resize(outpages, output_size): current_size = get_media_box_size(outpages) o = list(outpages) # rotate output_size if outpages would fit better out_ratio = output_size[0] / output_size[1] cur_ratio = current_size[0] / current_size[1] if out_ratio > 1 and cur_ratio <= 1 or out_ratio <= 1 and cur_ratio > 1: output_size = list(reversed(output_size)) scale, x_margin, y_margin = calculate_margins(output_size, current_size) for idx, page in enumerate(outpages): page = PageMerge().add(page) # scale page page[0].scale(scale) page[0].x += x_margin page[0].y += y_margin # set new mediabox size page.mbox = [0, 0] + output_size # replace original with resized page o[idx] = page.render() return o
def fixpage(*pages): """ Taken from example project in pdfrw. Puts two pages together into one """ result = PageMerge() + (x for x in pages if x is not None) result[-1].x += result[0].w return result.render()
def two_up(data): pdf = PdfReader(fdata=data) pages = PageMerge() + pdf.pages assert len(pages) == 2 left, right = pages rotation = 270 scale = 0.7071067811865476 # sqrt(0.5) x_increment = scale * pages.xobj_box[2] left.Rotate = rotation left.scale(scale) right.Rotate = rotation right.scale(scale) right.x = x_increment writer = PdfWriter() writer.addpage(pages.render()) # retain and update metadata pdf.Info.Creator = 'modulo-nic.py %s' % __version__ writer.trailer.Info = pdf.Info sys.stdout.write('Content-Type: application/x-pdf\n\n') writer.write(sys.stdout)
def save_with_even_pages(exam_id, exam_pdf_file): """Save a finalized exam pdf with evem number of pages. The exam is saved in the path returned by `get_exam_dir(exam_id)` with the name `exam.pdf`. If the pdf has an odd number of pages, an extra blank page is added at the end, this is specially usefull for printing and contatenating multiple copies at once. Parameters ---------- exam_id : int The exam identifier exam_pdf_file : str or File like object The exam pdf to be saved inthe data directory """ os.makedirs(exam_dir(exam_id), exist_ok=True) pdf_path = exam_pdf_path(exam_id) exam_pdf = PdfReader(exam_pdf_file) pagecount = len(exam_pdf.pages) if (pagecount % 2 == 0): exam_pdf_file.seek(0) exam_pdf_file.save(pdf_path) return new = PdfWriter() new.addpages(exam_pdf.pages) blank = PageMerge() box = exam_pdf.pages[0].MediaBox blank.mbox = box blank = blank.render() new.addpage(blank) new.write(pdf_path)
def splitpage(src): ''' Split a page into two (top and bottom) ''' # Yield a result for each half of the page for y_pos in (0, 0.5): # Create a blank, unsized destination page. page = PageMerge() # add a portion of the source page to it as # a Form XObject. page.add(src, viewrect=(0, y_pos, 1, 0.5)) # By default, the object we created will be # at coordinates (0, 0), which is the lower # left corner. To move it up on the page # to the top, we simply use its height # (which is half the source page height) as # its y value. page[0].y = page[0].h # When we render the page, the media box will # encompass (0, 0) and all the objects we have # placed on the page, which means the output # page will be the same size as the input page. yield page.render()
def get4_fedex(srcpages): scale = 0.88 srcpages = PageMerge() + srcpages x_increment, y_increment = (scale * i for i in srcpages.xobj_box[2:]) for i, page in enumerate(srcpages): page.scale(scale) return srcpages.render()
def _pdfrw_adjust(self, page): info = PageMerge().add(page) x1, y1, x2, y2 = info.xobj_box viewrect = (self.margin_x, self.margin_y, x2 - x1 - 2 * self.margin_x, y2 - y1 - 2 * self.margin_y) page = PageMerge().add(page, viewrect=viewrect) page[0].scale(self.scale) return page.render()
def fixpage(page, count=[0]): count[0] += 1 oddpage = (count[0] & 1) result = PageMerge() for rotation in (180 + 180 * oddpage, 180 * oddpage): result.add(page, rotate=rotation) result[1].x = result[0].w return result.render()
def get4(srcpages): scale = 0.5 srcpages = PageMerge() + srcpages x_increment, y_increment = (scale * i for i in srcpages.xobj_box[2:]) for i, page in enumerate(srcpages): page.scale(scale) page.x = x_increment if i & 1 else 0 page.y = 0 if i & 2 else y_increment return srcpages.render()
def test_is_landscape(self): page = PageMerge() + self.portrait_pdf[0] self.assertFalse(core.is_landscape(page)) page.rotate = 90 page = PageMerge() + page.render() self.assertTrue(core.is_landscape(page)) page.rotate = 90 page = PageMerge() + page.render() self.assertFalse(core.is_landscape(page)) page.rotate = 90 page = PageMerge() + page.render() self.assertTrue(core.is_landscape(page)) page = PageMerge() + self.landscape_pdf[0] self.assertTrue(core.is_landscape(page))
def add_signature(certname, signame, outname, under=True): if under not in (None, False, 0, '0', 'no', 'false', "False", ''): under = True else: under = False l = LinePos(certname) sigp = PdfReader(signame).pages[0] cert = PdfReader(certname) s = SigPos(sigp) m = PageMerge(cert.pages[0]).add(sigp, prepend=under) msig = m[not under] msig.x = (l.r + l.l) / 2 - (s.r + s.l) / 2 msig.y = l.h - l.t m.render() PdfWriter(outname, trailer=cert).write()
def get2(srcpages): scale = 0.5 srcpages = PageMerge() + srcpages.pages[:2] x_increment, y_increment = (scale * i for i in srcpages.xobj_box[2:]) for i, page in enumerate(srcpages): page.scale(scale) page.x = 0 if i == 0 else x_increment page.y = 0 return srcpages.render()
def get4_fedex(srcpages): scale = 0.88 srcpages = PageMerge() + srcpages x_increment, y_increment = (scale * i for i in srcpages.xobj_box[2:]) for i, page in enumerate(srcpages): page.scale(scale) # page.x = x_increment if i & 1 else 0 # page.y = 0 if i & 2 else y_increment # print "parrrrrrrrrrrrrrrrrrrrrr",page.x,page.y return srcpages.render()
def place8(srcpages): scale = 1 srcpages = PageMerge() + srcpages x_increment, y_increment = (scale * i for i in srcpages.xobj_box[2:]) for i, page in enumerate(srcpages): print(page.w) print(page.h) page.scale(scale, scale) page.x = (i % 4) * x_increment page.y = 0 if i < 4 else y_increment return srcpages.render()
def adjust(page, params): scale, margin, is_vertical = params info = PageMerge().add(page) x1, y1, x2, y2 = info.xobj_box if is_vertical == 1: viewrect = (0, margin / scale, x2, y2 - 2 * margin / scale) else: viewrect = (margin / scale, 0, x2 - 2 * margin / scale, y2) page = PageMerge().add(page, viewrect=viewrect) page[0].scale(scale) return page.render()
def get4(srcpages): if not pick.ship_label_bool: scale = 0.35 srcpages = PageMerge() + srcpages x_increment, y_increment = (scale * i for i in srcpages.xobj_box[2:]) for i, page in enumerate(srcpages): page.scale(scale) page.x = x_increment if i & 1 else 0 page.y = 0 if i & 2 else y_increment return srcpages.render() if pick.ship_label_bool: scale = 0.88 srcpages = PageMerge() + srcpages x_increment, y_increment = (scale * i for i in srcpages.xobj_box[2:]) for i, page in enumerate(srcpages): page.scale(scale) # page.x = x_increment if i & 1 else 0 # page.y = 0 if i & 2 else y_increment # print "parrrrrrrrrrrrrrrrrrrrrr",page.x,page.y return srcpages.render()
def make_card(): """Render a message via the API, then composite the render on top of an existing template, at the correct position. """ # render the message message_render = render_handwritten_msg(HANDWRITING_ID, MESSAGE_TO_RENDER) # wrap the render and the template files with pdfrw template_pdf = PdfReader('template.pdf') message_pdf = PdfReader(fdata=message_render) # set up our render as a "stamp" to put on the template stamp = PageMerge().add(message_pdf.pages[0])[0] # x is the distance from the left edge of the template to the left edge of the stamp: stamp.x = OFFSET_X_POINTS # y is the distance from the bottom edge of the template to the top edge of the stamp: stamp.y = CARD_H_POINTS - OFFSET_Y_POINTS pm = PageMerge(template_pdf.pages[0]) pm.add(stamp) pm.render() PdfWriter().write('out.pdf', template_pdf)
def put_pages_on_grid(pages, rows=2, cols=3): """Put pages on a grid on a single page.""" scale = 1 / max(rows, cols) source_pages = PageMerge() + pages x_increment, y_increment = (scale * i for i in source_pages.xobj_box[2:]) for page in source_pages: page.scale(scale) if i & 1: page.x = x_increment else: page.x = 0 if i & 2: page.y = 0 else: page.y = y_increment return source_pages.render()
def fixpage(page, width, height): result = PageMerge() result.add(page) if width > height: if width > 842: result[0].w = height * 1.6 result[0].x = 50 else: result[0].x = 0 result[0].w = height * 1.4 else: if height > 842: result[0].y = 125 result[0].w = width result[0].x = 0 return result.render()
def make_all_up(pages): result = PageMerge() # note: pagemerge() resizes based on content so we now have a # (pagecount)*width by height page. Ideally we'd then resize the page, but # this is fine for now since we can use print to scale in print programs. for page in pages: # p.scale(0.5) result.add(page) first_page_added = len(result) == 1 if first_page_added: continue added_page = result[-1] second_last_page_added = result[-2] added_page.x = second_last_page_added.x + second_last_page_added.w return result.render()
def initInfo(self): ''' initial booklet information ''' # initial booklet info = dictObj() if self.__inArgs.bookletSize: info['outBookSize'] = self.__inArgs.bookletSize info.update(PRINT_LAYOUT_DICT[info['outBookSize']]) info.update(PRINT_SIZE_DICT[info['outBookSize']]) self.info = info # blank page blank = PageMerge() blank.mbox = [0, 0, info.w, info.h] self.__blank = blank.render() # counter layout self.__counter = reduce( lambda x, y: x * y, [self.info['x'], self.info['y'], self.info['z']])
def pageLayout(self, seed): ''' page layout ''' pageLayoutList = self.genIndex(seed) for i in pageLayoutList: page = PageMerge() y_pos = 0 for j in i: x_pos = 0 for k in j: page.add(self.objs[k]) page[-1].scale(self.info.w / page[-1].w, self.info.h / page[-1].h) page[-1].x = x_pos * self.info.w page[-1].y = y_pos * self.info.h x_pos += 1 y_pos += 1 self.opages.append(page.render())
def _blank_page(width=DEFAULT_IMAGE_WIDTH, height=DEFAULT_IMAGE_HEIGHT): blank = PageMerge() blank.mbox = [0, 0, width, height] # 8.5 x 11 blank = blank.render() return blank
def pdf(rm_files_path, path_highlighter, pages, path_original_pdf, path_annotated_pdf, path_oap_pdf): """ Render pdf with annotations. The path_oap_pdf defines the pdf which includes only annotated pages. """ base_pdf = PdfReader(open(path_original_pdf, "rb")) # Parse remarkable files and write into pdf annotations_pdf = [] offsets = [] for page_nr in range(base_pdf.numPages): rm_file_name = "%s/%d" % (rm_files_path, page_nr) rm_file = "%s.rm" % rm_file_name if not os.path.exists(rm_file): annotations_pdf.append(None) offsets.append(None) continue if hasattr(base_pdf, "Root") and hasattr(base_pdf.Root, "Pages") and hasattr( base_pdf.Root.Pages, "MediaBox"): default_layout = base_pdf.Root.Pages.MediaBox else: default_layout = None page_layout = PDFPageLayout(base_pdf.pages[page_nr], default_layout=default_layout) if page_layout.layout is None: annotations_pdf.append(None) offsets.append(None) continue page_file = os.path.join(path_highlighter, f"{pages[page_nr]}.json") annotated_page, offset = _render_rm_file( rm_file_name, page_layout=page_layout, page_file=page_file, ) if len(annotated_page.pages) <= 0: annotations_pdf.append(None) else: page = annotated_page.pages[0] annotations_pdf.append(page) offsets.append(offset) # Merge annotations pdf and original pdf writer_full = PdfWriter() writer_oap = PdfWriter() for i in range(base_pdf.numPages): annotations_page = annotations_pdf[i] if annotations_page is not None: # The annotations page is at least as large as the base PDF page, # so we merge the base PDF page under the annotations page. merger = PageMerge(annotations_page) pdf = merger.add(base_pdf.pages[i], prepend=True)[0] pdf.x -= offsets[i][0] pdf.y -= offsets[i][1] merger.render() writer_oap.addpage(annotations_page) writer_full.addpage(annotations_page) else: writer_full.addpage(base_pdf.pages[i]) writer_full.write(path_annotated_pdf) writer_oap.write(path_oap_pdf)
def fixpage(*pages): result = PageMerge() + (x for x in pages if x is not None) result[-1].x += result[0].w return result.render()
if args.padding: pad_to = 4 else: pad_to = 2 # Make sure we have a correct number of sides print(len(ipages)) ipages += [None] * (-len(ipages) % 4) # ipages += [None]*(-len(ipages)%4) print(len(ipages)) opages = [] blank = PageMerge() blank.mbox = [0, 0, 419, 192] # 8.5 x 11 blank = blank.render() ipages.reverse() while len(ipages) > 0: page1 = ipages.pop() if page1 == None: page1 = blank page2 = ipages.pop() if page2 == None: page2 = blank opages.append(fixpage(page1, page2)) # opages.append(fixpage(ipages[2],blank)) # # opages.append(fixpage(ipages.pop())) # opages += ipages
def generate_certificate_pdf(person: Person, reason: int, start: datetime, generated: datetime) -> str: """ Generate the certificate required when leaving the place of confinement. Arguments --------- person: :class:`Person` For whom the certificate is generated. reason: `int` For which the person is leaving her place of confinement. This is an index into ``REASONS``. start: `datetime` Date and time the person is leaving her place of confinement. generated: `datetime` Date and time the certificate is generated. Returns ------- str Path to the PDF file generated. """ def cm_to_point(cm: float) -> int: return int(cm / 2.54 * 72) if sys.platform == 'ios': LEGEND_FONT = 'Helvetica' LEGEND_FONT_SIZE = 24 else: LEGEND_FONT = 'arial.ttf' LEGEND_FONT_SIZE = 24 font = ImageFont.truetype(LEGEND_FONT, LEGEND_FONT_SIZE) fields = [ TextField(text=f"{person.first_name} {person.last_name}", font=font, x=3.27, y=24.8, scale=.47), TextField(text=person.birthdate, font=font, x=3.27, y=24.15, scale=.47), TextField(text=person.birthplace, font=font, x=7.55, y=24.15, scale=.47), TextField(text=f"{person.address} {person.postal_code} {person.city} ", font=font, x=3.68, y=23.476, scale=.47), TextField(text="X" if reason == 0 else " ", font=font, x=1.625, y=19.52, scale=.37), TextField(text="X" if reason == 1 else " ", font=font, x=1.625, y=17.02, scale=.37), TextField(text="X" if reason == 2 else " ", font=font, x=1.625, y=15.32, scale=.37), TextField(text="X" if reason == 3 else " ", font=font, x=1.625, y=14.47, scale=.37), TextField(text="X" if reason == 4 else " ", font=font, x=1.66, y=12.32, scale=.37), TextField(text=person.city, font=font, x=2.8, y=2.7, scale=.47), TextField(text=start.strftime('%d/%m/%Y'), font=font, x=2.22, y=2.05, scale=.47), TextField(text=start.strftime('%H:%M'), font=font, x=8.02, y=2.05, scale=.47), QRCodeField(person=person, reason=reason, start=start, generated=generated, x=15.35, y=.9, scale=.65) ] def set_position(obj: RectXObj, x: float, y: float, scale: float) -> None: obj.x = cm_to_point(x) obj.y = cm_to_point(y) obj.w *= scale # Generate page 1 page1_xobj = PageMerge(PdfReader(TEMPLATE_PDF).pages[0]) for field in fields: pdf = PdfReader(field.filename).pages[0] page1_xobj.add(pdf) set_position(page1_xobj[-1], field.x, field.y, field.scale) if isinstance(field, QRCodeField): qrcode = pdf page1 = page1_xobj.render() # Generate page 2 qrcode_xobj = PageMerge().add(qrcode) set_position(qrcode_xobj[0], 1.3, 16.9, 2.15) page2 = qrcode_xobj.render() page2.MediaBox = page1.MediaBox # Generate certificate document PdfWriter().addpages([page1, page2]).write(CERTIFICATE_PDF) # Remove temporary files. for field in fields: Path(field.filename).unlink() return CERTIFICATE_PDF
action='store_const', const=True, default=False, help='reverses the even pages before shuffling') args = parser.parse_args() # The shuffling magic even = PdfReader(args.evenFile[0]) odd = PdfReader(args.oddFile[0]) isEvenReversed = args.evenrev; isOddReversed = args.oddrev; all = PdfWriter() blank = PageMerge() blank.mbox = [0, 0, 612, 792] # 8.5 x 11 blank = blank.render() if isEvenReversed and not isOddReversed: for i in range(0, len(odd.pages)): all.addpage(odd.pages[i]) all.addpage(even.pages[len(even.pages)-1-i]) elif isOddReversed and not isEvenReversed: for i in range(0, len(odd.pages)): all.addpage(odd.pages[len(odd.pages)-1-i]) all.addpage(even.pages[i]) elif isEvenReversed and isOddReversed: for i in range(0, len(odd.pages)): all.addpage(odd.pages[len(odd.pages)-1-i]) all.addpage(even.pages[len(even.pages)-1-i]) else: for x,y in zip(odd.pages, even.pages):
def merge(pages, rotation, binding): page = PageMerge() + (p for p in pages) page = set_binding(page, binding, rotation) return page.render()
def anim_pdf(name, rotate=0, history=True, lines=True, flatten=False, place='left', add_name='_anim', two_screens=False, skip=0): # The optional arguments are also available as command line options and explained in anim_pdf_command_line() # check whether file exists if not isfile(name + '.pdf'): raise Exception('File ' + name + '.pdf not found.') # integrate annotations (if required) and read file gs = Ghostscript() if flatten: gs.flatten_pdf(name, name + '_flat') pdf = PdfReader(name + '_flat.pdf') else: pdf = PdfReader(name + '.pdf') out = PdfWriter() for j in range(len(pdf.pages)-skip): print('slide', j+1) pdf.pages[j].Rotate = rotate # get pixels temp_out = PdfWriter() temp_out.addpage(pdf.pages[j]) temp_out.write('temp' + str(j) + '.pdf') gs.pdf2jpg('temp' + str(j)) image = Image.open('temp' + str(j) + '.jpg') pixels = image.load() # determine background color from first page (usually white) and create background image if j == 0: bkgr = background(image.size[0], image.size[1], pixels) Image.new('RGB', (1, 1), bkgr).save('white.pdf') white = PdfReader('white.pdf').pages[0] if lines: # determine data for animation ends = endpoints(image.size[0], image.size[1], pixels) else: ends = [image.size[1]-1] for i in range(len(ends)): # make animation merge_anim = PageMerge() merge_anim.add(pdf.pages[j]) merge_anim.add(white) factor_w = merge_anim[0].w/merge_anim[1].w factor_h = (1-ends[i]/image.size[1])*merge_anim[0].h/merge_anim[1].h merge_anim[1].scale(factor_w,factor_h) merge_anim_rendered = merge_anim.render() if not history: out.addpage(merge_anim_rendered) else: history_first = ((place == 'top') or (place == 'left')) and ((j>=1) or two_screens) horizontal = (place == 'left') or (place == 'right') merge_two = PageMerge() if history_first: h = 0 m = 1 else: m = 0 h = 1 if not history_first: merge_two.add(merge_anim_rendered) if j>=1: merge_two.add(pdf.pages[j-1]) else: merge_two.add(white) if history_first: merge_two.add(merge_anim_rendered) if j==0: merge_two[h].scale(merge_two[m].w/merge_two[h].w,merge_two[m].h/merge_two[h].h) if horizontal: merge_two[1].x = merge_two[0].w else: merge_two[0].y = merge_two[1].h out.addpage(merge_two.render()) remove('temp' + str(j) + '.jpg') remove('temp' + str(j) + '.pdf') if flatten: remove(name + '_flat.pdf') out.write(name + add_name + '.pdf') remove('white.pdf')
def create_blank_copy(page): blank_page = PageMerge() blank_page.mbox = page.MediaBox blank_page.rotate = page.Rotate return blank_page.render()