def generateCollage(self, session): file_name = 'collage.pdf' #TODO image should be created in a temp directory pdf = Canvas(file_name, pagesize=self._pagesize) # add metadata pdf.setAuthor('photobooth') #TODO add app version to author pdf.setSubject('wedding photos') pdf.setTitle('pictures for session %s' % session.get_name()) pdf.setKeywords(('wedding', 'pictures', 'photobooth')) # add pictures #TODO add padding (total_width, total_height) = self._pagesize (image_width, image_height) = (total_width, total_height / len(session.get_photos())) for (i, photo) in enumerate(session.get_photos()): pdf.drawInlineImage(photo, 0, i * image_height, image_width, image_height, preserveAspectRatio=True, anchor='n') pdf.showPage() pdf.save() return file_name
def create_pdf(image_paths, output_filepath): image_paths.sort() pdf = Canvas(output_filepath) pdf.setAuthor("MangaCreator") for image_path in image_paths: image = Image.open(image_path) width, height = A4 pdf.drawInlineImage(image, x=0, y=0, width=width, height=height) pdf.showPage() pdf.save()
def create_pdf(image_paths, output_filepath): image_paths.sort() pdf = Canvas(output_filepath) pdf.setAuthor("ComicConverter") for image_path in image_paths: image = Image.open(image_path) width, height = A4 pdf.drawInlineImage(image, x=0, y=0, width=width, height=height) pdf.showPage() pdf.save()
def packprint(outfile, files): PAGESIZE = (A4[0]*4, A4[1]*4) padding = (30*mm, 60*mm) canvas = Canvas(outfile, pagesize=PAGESIZE) for j, i in enumerate(range(0, len(files), 4)): curfiles = [f for f in files[i:i+4]] for idx, f in enumerate(curfiles): im = Image.open(f) im = drawBorders(im) if idx == 0: canvas.drawInlineImage(im, padding[0], PAGESIZE[1]-padding[1]-im.size[1], width=im.size[0], height=im.size[1]) elif idx == 1: canvas.drawInlineImage(im, padding[0], padding[1], width=im.size[0], height=im.size[1]) elif idx == 2: canvas.drawInlineImage(im, PAGESIZE[0]-padding[0]-im.size[0], PAGESIZE[1]-padding[1]-im.size[1], width=im.size[0], height=im.size[1]) else: canvas.drawInlineImage(im, PAGESIZE[0]-padding[0]-im.size[0], padding[1], width=im.size[0], height=im.size[1]) canvas.showPage() canvas.save()
def test_single_page_inline_image(): filename = os.path.join(TEST_OUTPUT, "image-mono-inline.pdf") pdf = Canvas(filename, pagesize=(8 * 72, 6 * 72)) with NamedTemporaryFile() as im_tmp: im = Image.new("1", (8, 8), 0) for n in range(8): im.putpixel((n, n), 1) im.save(im_tmp.name, format="PNG") # Draw image in a 72x72 pt or 1"x1" area pdf.drawInlineImage(im_tmp.name, 0, 0, width=72, height=72) pdf.showPage() pdf.save() with pytest.raises(NotImplementedError): pageinfo.pdf_get_all_pageinfo(filename)
def test_single_page_inline_image(): filename = os.path.join(TEST_OUTPUT, 'image-mono-inline.pdf') pdf = Canvas(filename, pagesize=(8 * 72, 6 * 72)) with NamedTemporaryFile() as im_tmp: im = Image.new('1', (8, 8), 0) for n in range(8): im.putpixel((n, n), 1) im.save(im_tmp.name, format='PNG') # Draw image in a 72x72 pt or 1"x1" area pdf.drawInlineImage(im_tmp.name, 0, 0, width=72, height=72) pdf.showPage() pdf.save() with pytest.raises(NotImplementedError): pageinfo.pdf_get_all_pageinfo(filename)
def test_single_page_inline_image(eight_by_eight, outdir): filename = outdir / 'image-mono-inline.pdf' pdf = Canvas(str(filename), pagesize=(8 * 72, 6 * 72)) # Draw image in a 72x72 pt or 1"x1" area pdf.drawInlineImage(eight_by_eight, 0, 0, width=72, height=72) pdf.showPage() pdf.save() info = pdfinfo.PdfInfo(filename) print(info) pdfimage = info[0].images[0] assert isclose(pdfimage.dpi.x, 8) assert pdfimage.color == Colorspace.gray assert pdfimage.width == 8
def _generate_pattern(image, flip=True): template = image_ops.generate_template(image, flip=flip) image_buf = BytesIO() template.save(image_buf, format="PNG") bead_counts = image_ops.count_beads(image) # Start PDF data = BytesIO() # bottomup is forced because reportlab treats images that way? # Or we could flip the image ourselves and still specify the bottom # right corner? canvas = Canvas(data, bottomup=1, pagesize=letter) # page 1: packing list and instructions y = 10 * inch color_count = len(bead_counts.keys()) column = 0 left_margin = 0.5 * inch for index, color_name in enumerate(sorted(bead_counts.keys())): if column == 0 and index >= color_count / 2.0: column = 1 left_margin = 4.25 * inch y = 10 * inch count = bead_counts[color_name] color_file = color_name.replace(" ", "_") + ".png" canvas.drawInlineImage( f"data/color_images/bitmap/{color_file}", x=left_margin+0.5*inch, y=y-0.04*inch, width=0.2*inch, height=0.2*inch ) canvas.drawCentredString(left_margin+0.25*inch, y, str(count)) canvas.drawString(left_margin+0.75*inch, y, color_name) y -= 0.2 * inch canvas.showPage() # page 2: template canvas.drawInlineImage( template, x=0.25*inch, y=0.5*inch, width=8*inch, height=10*inch, ) canvas.showPage() # Finalize and return canvas.save() data.seek(0) return data.read()
def save_pdf(self, filename, margins=(1, 1)): ''' Make and save a PDF of this coverage plot, including a legend. Margins are expressed in inches: (top-bottom, left-right). ''' from reportlab.lib.units import inch from reportlab.lib.pagesizes import letter from reportlab.pdfgen.canvas import Canvas c = Canvas(filename, pagesize=letter) # Compute margins. margin_top, margin_left = margins margin_top *= inch margin_left *= inch whole_page_width, whole_page_height = letter page_top = whole_page_height - margin_top page_left = margin_left page_width = whole_page_width - 2 * margin_left # Show the main image. image = self.img image_width = page_width image_height = image_width / image.size[0] * image.size[1] image_x = page_left image_y = page_top - image_height c.drawInlineImage(image, image_x, image_y, width=image_width, height=image_height) # Draw legends beneath the image. textobject = c.beginText() textobject.setTextOrigin(page_left, image_y - .5 * inch) textobject.setFont('Helvetica', 14) for name, color in izip(self.names, self.colors): textobject.setFillColorRGB(*color) textobject.textLine(name) c.drawText(textobject) # Done. c.showPage() c.save()
def test_single_page_inline_image(outdir): filename = outdir / 'image-mono-inline.pdf' pdf = Canvas(str(filename), pagesize=(8 * 72, 6 * 72)) with NamedTemporaryFile() as im_tmp: im = Image.new('1', (8, 8), 0) for n in range(8): im.putpixel((n, n), 1) im.save(im_tmp.name, format='PNG') # Draw image in a 72x72 pt or 1"x1" area pdf.drawInlineImage(im_tmp.name, 0, 0, width=72, height=72) pdf.showPage() pdf.save() pdfinfo = pageinfo.pdf_get_all_pageinfo(str(filename)) print(pdfinfo) pdfimage = pdfinfo[0]['images'][0] assert (pdfimage['dpi_w'] - 8) < 1e-5 assert pdfimage['color'] != '-' assert pdfimage['width'] == 8
def generateCollage(self,session): file_name = 'collage.pdf' #TODO image should be created in a temp directory pdf = Canvas(file_name,pagesize=self._pagesize) # add metadata pdf.setAuthor('photobooth') #TODO add app version to author pdf.setSubject('wedding photos') pdf.setTitle('pictures for session %s' % session.get_name()) pdf.setKeywords(('wedding', 'pictures','photobooth')) # add pictures #TODO add padding (total_width, total_height) = self._pagesize (image_width, image_height) = (total_width, total_height / len(session.get_photos())) for (i,photo) in enumerate(session.get_photos()): pdf.drawInlineImage(photo,0,i * image_height, image_width, image_height, preserveAspectRatio=True, anchor='n') pdf.showPage() pdf.save() return file_name
def test_single_page_inline_image(outdir): filename = outdir / 'image-mono-inline.pdf' pdf = Canvas(str(filename), pagesize=(8 * 72, 6 * 72)) im = Image.new('1', (8, 8), 0) for n in range(8): im.putpixel((n, n), 1) # Draw image in a 72x72 pt or 1"x1" area pdf.drawInlineImage(im, 0, 0, width=72, height=72) pdf.showPage() pdf.save() info = pdfinfo.PdfInfo(filename) print(info) pdfimage = info[0].images[0] assert isclose(pdfimage.dpi.x, 8) assert pdfimage.color == Colorspace.gray assert pdfimage.width == 8
def test_single_page_inline_image(outdir): filename = outdir / 'image-mono-inline.pdf' pdf = Canvas(str(filename), pagesize=(8 * 72, 6 * 72)) with NamedTemporaryFile() as im_tmp: im = Image.new('1', (8, 8), 0) for n in range(8): im.putpixel((n, n), 1) im.save(im_tmp.name, format='PNG') # Draw image in a 72x72 pt or 1"x1" area pdf.drawInlineImage(im_tmp.name, 0, 0, width=72, height=72) pdf.showPage() pdf.save() pdf = pdfinfo.PdfInfo(filename) print(pdf) pdfimage = pdf[0].images[0] assert isclose(pdfimage.xres, 8) assert pdfimage.color == Colorspace.rgb # reportlab produces color image assert pdfimage.width == 8
def test_single_page_inline_image(): filename = os.path.join(TEST_OUTPUT, 'image-mono-inline.pdf') pdf = Canvas(filename, pagesize=(8*72, 6*72)) with NamedTemporaryFile() as im_tmp: im = Image.new('1', (8, 8), 0) for n in range(8): im.putpixel((n, n), 1) im.save(im_tmp.name, format='PNG') # Draw image in a 72x72 pt or 1"x1" area pdf.drawInlineImage(im_tmp.name, 0, 0, width=72, height=72) pdf.showPage() pdf.save() pdfinfo = pageinfo.pdf_get_all_pageinfo(filename) print(pdfinfo) pdfimage = pdfinfo[0]['images'][0] assert (pdfimage['dpi_w'] - 8) < 1e-5 assert pdfimage['color'] != '-' assert pdfimage['width'] == 8
def test_single_page_inline_image(outdir): filename = outdir / 'image-mono-inline.pdf' pdf = Canvas(str(filename), pagesize=(8*72, 6*72)) with NamedTemporaryFile() as im_tmp: im = Image.new('1', (8, 8), 0) for n in range(8): im.putpixel((n, n), 1) im.save(im_tmp.name, format='PNG') # Draw image in a 72x72 pt or 1"x1" area pdf.drawInlineImage(im_tmp.name, 0, 0, width=72, height=72) pdf.showPage() pdf.save() pdf = pdfinfo.PdfInfo(filename) print(pdf) pdfimage = pdf[0].images[0] assert isclose(pdfimage.xres, 8) assert pdfimage.color == Colorspace.rgb # reportlab produces color image assert pdfimage.width == 8
def export(grid, locked_cells): # Locate the Desktop as initial save path pdf_default_title = 'PySudoku.pdf' initial_save_path = join(expanduser('~'), 'Desktop/') try: # Hide Tkinter window Tk().withdraw() # Open dialog window from Tkinter pdf = filedialog.asksaveasfile(initialdir=initial_save_path, initialfile=pdf_default_title, title='Export as pdf', defaultextension='.pdf', filetypes=[('PDF file', '.pdf')]) # Generate pdf sudoku_file = Canvas(pdf.name, pagesize=A4) # Draw logo and board sudoku_file.drawInlineImage('images/pdf/pdf_logo.png', 25, 715) sudoku_file.drawInlineImage('images/pdf/pdf_board.png', 48, 120) # Set custom font pdfmetrics.registerFont( ttfonts.TTFont('Ubuntu-Regular', 'fonts/Ubuntu-Regular.ttf')) sudoku_file.setFont('Ubuntu-Regular', 58) # Draw numbers on the board for cell in locked_cells: if cell in grid_to_pdf.keys(): sudoku_file.drawString(grid_to_pdf[cell][0], grid_to_pdf[cell][1], str(grid[cell])) sudoku_file.setTitle(pdf.name[len(initial_save_path):]) sudoku_file.save() except AttributeError: pass
def save_pdf(self, filename, margins=(1,1)): ''' Make and save a PDF of this coverage plot, including a legend. Margins are expressed in inches: (top-bottom, left-right). ''' from reportlab.lib.units import inch from reportlab.lib.pagesizes import letter from reportlab.pdfgen.canvas import Canvas c = Canvas(filename, pagesize=letter) # Compute margins. margin_top, margin_left = margins margin_top *= inch; margin_left *= inch whole_page_width, whole_page_height = letter page_top = whole_page_height - margin_top page_left = margin_left page_width = whole_page_width - 2*margin_left # Show the main image. image = self.img image_width = page_width image_height = image_width / image.size[0] * image.size[1] image_x = page_left image_y = page_top - image_height c.drawInlineImage(image, image_x, image_y, width=image_width, height=image_height) # Draw legends beneath the image. textobject = c.beginText() textobject.setTextOrigin(page_left, image_y - .5*inch) textobject.setFont('Helvetica', 14) for name, color in izip(self.names, self.colors): textobject.setFillColorRGB(*color) textobject.textLine(name) c.drawText(textobject) # Done. c.showPage() c.save()
def createPFD(self): logToConsole( f"User @{self.user_id}(chat_id:{self.chat_id}) uploaded and combined the pictures into {self.document.name}." ) canvas = Canvas(filename=self.document, pageCompression=1) canvas.setTitle(self.document.name) canvas.setAuthor(self.author) for image in self.images: bytes = BytesIO(bot.getFile(image).download_as_bytearray()) page = Image.open(bytes).convert("RGBA") bytes.close() page_width, page_height = page.size draw_width, draw_height = page_width, page_height if page_width > page_height: canvas.setPageSize((draw_width, draw_height)) else: canvas.setPageSize((draw_width, draw_height)) canvas.drawInlineImage(page, 0, 0, width=draw_width, height=draw_height) canvas.showPage() canvas.save()
set_large_font(title_page) title_page.drawCentredString( paper_input[0] / 2, paper_input[1] * 0.9, title) # write the subtitle set_medium_font(title_page) for i, t in enumerate(subtitle.splitlines()): title_page.drawCentredString( paper_input[0] / 2, paper_input[1] * 0.15 - (i * 25 / font_scaling), t) # add the title image title_image = Image.open(title_page_image) # crop image to 60% of the size of the page cropped_image_size = (int(paper_input[0] * 0.6), int(paper_input[1] * 0.6)) title_image = title_image.resize(cropped_image_size) # Add picture x centered, bottom corner at 20% of page height x = paper_input[0] / 2 - cropped_image_size[0] / 2 title_page.drawInlineImage(title_image, x, paper_input[1] * 0.2) title_page.save() # Copyright page copyright_pdf = os.path.join(temp_dir, '0001_copyright.pdf') copyright_page = Canvas(copyright_pdf, pagesize=paper_input) # Add the copyright info to the address draw_paragraph(copyright_page, _copyright + '\n' * 3 + ntm_address, 0.9, 'S') copyright_page.save() preface_pdf = os.path.join(temp_dir, '0002_preface.pdf') preface_page = Canvas(preface_pdf, pagesize=paper_input) # write the English and Tok Pisin prefaces draw_paragraph(preface_page, preface + '\n' * 3 + tpi_preface, 0.75, 'S')
def to_pdf(self, imageFileName, outFileName, fontname="Courier", fontsize=8): """ Creates a PDF file with an image superimposed on top of the text. Text is positioned according to the bounding box of the lines in the hOCR file. The image need not be identical to the image used to create the hOCR file. It can be scaled, have a lower resolution, different color mode, etc. """ if self.hocr is None: # warn that no text will be embedded in the output PDF print "Warning: No hOCR file specified. PDF will be image-only." im = Image.open(imageFileName) imwidthpx, imheightpx = im.size if 'dpi' in im.info: width = float(im.size[0])/im.info['dpi'][0] height = float(im.size[1])/im.info['dpi'][1] else: # we have to make a reasonable guess # set to None for now and try again using info from hOCR file width = height = None ocr_dpi = (300, 300) # a default, in case we can't find it # get dimensions of the OCR, which may not match the image if self.hocr is not None: for div in self.hocr.findall(".//%sdiv"%(self.xmlns)): if div.attrib['class'] == 'ocr_page': coords = self.element_coordinates(div) ocrwidth = coords[2]-coords[0] ocrheight = coords[3]-coords[1] if width is None: # no dpi info with the image # assume OCR was done at 300 dpi width = ocrwidth/300 height = ocrheight/300 ocr_dpi = (ocrwidth/width, ocrheight/height) break # there shouldn't be more than one, and if there is, we don't want it if width is None: # no dpi info with the image, and no help from the hOCR file either # this will probably end up looking awful, so issue a warning print "Warning: DPI unavailable for image %s. Assuming 96 DPI."%(imageFileName) width = float(im.size[0])/96 height = float(im.size[1])/96 # create the PDF file pdf = Canvas(outFileName, pagesize=(width*inch, height*inch), pageCompression=1) # page size in points (1/72 in.) # put the image on the page, scaled to fill the page pdf.drawInlineImage(im, 0, 0, width=width*inch, height=height*inch) if self.hocr is not None: for line in self.hocr.findall(".//%sspan"%(self.xmlns)): if line.attrib['class'] == 'ocr_line': coords = self.element_coordinates(line) text = pdf.beginText() text.setFont(fontname, fontsize) text.setTextRenderMode(3) # invisible # set cursor to bottom left corner of line bbox (adjust for dpi) text.setTextOrigin((float(coords[0])/ocr_dpi[0])*inch, (height*inch)-(float(coords[3])/ocr_dpi[1])*inch) # scale the width of the text to fill the width of the line's bbox text.setHorizScale((((float(coords[2])/ocr_dpi[0]*inch)-(float(coords[0])/ocr_dpi[0]*inch))/pdf.stringWidth(line.text.rstrip(), fontname, fontsize))*100) # write the text to the page text.textLine(line.text.rstrip()) pdf.drawText(text) # finish up the page and save it pdf.showPage() pdf.save()
def draw(self, invoice, items_page=10): """ Draws the invoice """ buffer = cStringIO.StringIO() invoice_items = invoice['items'] pages = max((len(invoice_items)-2)/items_page+1,1) canvas = Canvas(buffer, pagesize=self.page_size) for page in range(pages): canvas.translate(0, 29.7 * cm) canvas.setFont(self.font_face, 10) canvas.saveState() canvas.setStrokeColorRGB(0.9, 0.5, 0.2) canvas.setFillColorRGB(0.2, 0.2, 0.2) canvas.setFont(self.font_face, 16) canvas.drawString(1 * cm, -1 * cm, invoice.get('title','')) if self.logo: canvas.drawInlineImage(self.logo, 1 * cm, -1 * cm, 250, 16) canvas.setLineWidth(4) canvas.line(0, -1.25 * cm, 21.7 * cm, -1.25 * cm) canvas.restoreState() canvas.saveState() notes = listify(invoice.get('notes','')) textobject = canvas.beginText(1 * cm, -25 * cm) for line in notes: textobject.textLine(line) canvas.drawText(textobject) textobject = canvas.beginText(18 * cm, -28 * cm) textobject.textLine('Pag.%s/%s' % (page+1,pages)) canvas.drawText(textobject) canvas.restoreState() canvas.saveState() business_details = listify(invoice.get('from','FROM:')) canvas.setFont(self.font_face, 9) textobject = canvas.beginText(13 * cm, -2.5 * cm) for line in business_details: textobject.textLine(line) canvas.drawText(textobject) canvas.restoreState() canvas.saveState() client_info = listify(invoice.get('to','TO:')) textobject = canvas.beginText(1.5 * cm, -2.5 * cm) for line in client_info: textobject.textLine(line) canvas.drawText(textobject) canvas.restoreState() textobject = canvas.beginText(1.5 * cm, -6.75 * cm) textobject.textLine(u'Invoice ID: %s' % invoice.get('id','<invoice id>')) textobject.textLine(u'Invoice Date: %s' % invoice.get('date',datetime.date.today())) textobject.textLine(u'Client: %s' % invoice.get('client_name','<invoice client>')) canvas.drawText(textobject) items = invoice_items[1:][page*items_page:(page+1)*items_page] if items: data = [invoice_items[0]] for item in items: data.append([ self.format_currency(x) if isinstance(x,float) else x for x in item]) righta = [k for k,v in enumerate(items[0]) if isinstance(v,(int,float,Decimal))] if page == pages-1: total = self.format_currency(invoice['total']) else: total = '' data.append(['']*(len(items[0])-1)+[total]) colWidths = [2.5*cm]*len(items[0]) colWidths[1] = (21.5-2.5*len(items[0]))*cm table = Table(data, colWidths=colWidths) table.setStyle([ ('FONT', (0, 0), (-1, -1), self.font_face), ('FONTSIZE', (0, 0), (-1, -1), 8), ('TEXTCOLOR', (0, 0), (-1, -1), (0.2, 0.2, 0.2)), ('GRID', (0, 0), (-1, -2), 1, (0.7, 0.7, 0.7)), ('GRID', (-1, -1), (-1, -1), 1, (0.7, 0.7, 0.7)), ('BACKGROUND', (0, 0), (-1, 0), (0.8, 0.8, 0.8)), ]+[('ALIGN',(k,0),(k,-1),'RIGHT') for k in righta]) tw, th, = table.wrapOn(canvas, 15 * cm, 19 * cm) table.drawOn(canvas, 1 * cm, -8 * cm - th) if page == pages-1: items = invoice['totals'][1:] if items: data = [invoice['totals'][0]] for item in items: data.append([ self.format_currency(x) if isinstance(x,float) else x for x in item]) righta = [k for k,v in enumerate(items[0]) if isinstance(v,(int,float,Decimal))] total = self.format_currency(invoice['total']) data.append(['']*(len(items[0])-1)+[total]) colWidths = [2.5*cm]*len(items[0]) colWidths[1] = (21.5-2.5*len(items[0]))*cm table = Table(data, colWidths=colWidths) table.setStyle([ ('FONT', (0, 0), (-1, -1), self.font_face), ('FONTSIZE', (0, 0), (-1, -1), 8), ('TEXTCOLOR', (0, 0), (-1, -1), (0.2, 0.2, 0.2)), ('GRID', (0, 0), (-1, -2), 1, (0.7, 0.7, 0.7)), ('GRID', (-1, -1), (-1, -1), 1, (0.7, 0.7, 0.7)), ('BACKGROUND', (0, 0), (-1, 0), (0.8, 0.8, 0.8)), ]+[('ALIGN',(k,0),(k,-1),'RIGHT') for k in righta]) tw, th, = table.wrapOn(canvas, 15 * cm, 19 * cm) table.drawOn(canvas, 1 * cm, -18 * cm - th) canvas.showPage() canvas.save() return buffer.getvalue()
def to_pdf(self, out_filename, image_filename, show_bounding_boxes, hocr_file, dpi, font_name="Helvetica"): """ Creates a PDF file with an image superimposed on top of the text. Text is positioned according to the bounding box of the lines in the hOCR file. The image need not be identical to the image used to create the hOCR file. It can have a lower resolution, different color mode, etc. """ hocr_tree = etree.ElementTree() hocr_tree.parse(hocr_file) xmlns = self.lookup_namespace(hocr_tree) pt_page_height, pt_page_width = self.calculate_pt_dimensions(dpi, hocr_tree, xmlns) # no width and height definition in the ocr_image element of the hocr file if pt_page_width is None: print ("No page dimension found in the hocr file") sys.exit(1) # Create the PDF file. Page size in points (1/72 in.) pdf = Canvas(out_filename, pagesize=(pt_page_width, pt_page_height), pageCompression=1) # draw bounding box for each paragraph green = Color(0.1, 0.5, 0.1) lime_green = Color(0.8, 1, 0) blue = Color(0, 1, 1) red = Color(1, 0, 0) black = Color(0, 0, 0) word_dict = dict() word_array = dict() paragraph_count = 0 for paragraph_element in hocr_tree.findall(".//%sp[@class='%s']" % (xmlns, "ocr_par")): element_text = self._get_element_text(paragraph_element).rstrip() if len(element_text) == 0: continue paragraph_count += 1 word_array[paragraph_count] = {} if show_bounding_boxes: x1, y1, x2, y2 = self.convert_px_coordinates_to_pt(self.element_coordinates(paragraph_element), dpi) self.draw_box(pdf, pt_page_height, x1, y1, x2, y2, lime_green, blue, is_filled=1, line_width=4) self.annotate_box( pdf, x1, pt_page_height - y1, "p-%d_%s" % (paragraph_count, paragraph_element.get("id").rsplit("_", 1)[1]), ) line_count = 0 for line_element in paragraph_element.findall(".//%sspan[@class='%s']" % (xmlns, "ocr_line")): element_text = self._get_element_text(line_element).rstrip() if len(element_text) == 0: continue line_count += 1 word_array[paragraph_count][line_count] = {} if show_bounding_boxes: x1, y1, x2, y2 = self.convert_px_coordinates_to_pt(self.element_coordinates(line_element), dpi) self.draw_box(pdf, pt_page_height, x1, y1, x2, y2, green, blue, is_filled=1, line_width=1) self.annotate_box( pdf, x1, pt_page_height - y2, "l-%d_%s" % (line_count, line_element.get("id").rsplit("_", 1)[1]), right_align=1, ) word_count = 0 for word_element in paragraph_element.findall(".//%sspan[@class='%s']" % (xmlns, "ocrx_word")): element_text = self._get_element_text(word_element).rstrip() element_text = self.replace_unsupported_chars(element_text) if len(element_text) == 0: continue word_count += 1 coordinates = self.element_coordinates(word_element) x1, y1, x2, y2 = HocrTransform2.convert_px_coordinates_to_pt(coordinates, dpi) # draw the bbox border if show_bounding_boxes: self.draw_box(pdf, pt_page_height, x1, y1, x2, y2, red, black, line_width=0.5, is_dashed=1) self.annotate_box(pdf, x1, pt_page_height - y1, "w-%d" % word_count, top_align=1) # count_path = 'p(%d)l(%d)w(%d)' % (paragraph_count, line_count, word_count) # id_path = '%s %s %s' % (paragraph_element.get('id'), line_element.get('id'), word_element.get('id')) # print '%s] %s = "%s"' % (count_path, id_path, element_text) # word_dict[word_element.attrib['id']] = self._get_element_text(word_element) # print '%s="%s"' % (word_element.attrib['id'], word_dict[word_element.attrib['id']]) word_array[paragraph_count][line_count][word_count] = { "p": paragraph_count, "l": line_count, "w": word_count, "id": word_element.attrib["id"], "word": element_text, "path": hocr_tree.getpath(word_element), } print word_array[paragraph_count][line_count][word_count] fontsize = self.px2pt(coordinates[3] - coordinates[1], dpi) pdf.setLineWidth(1) pdf.setDash([], 0) pdf.setStrokeColor(black) pdf.setFillColor(black) text = pdf.beginText() text.setTextRenderMode(0) text.setFont(font_name, fontsize) text.setTextOrigin(x1, pt_page_height - y2) text.setHorizScale(100 * (x2 - x1) / pdf.stringWidth(element_text, font_name, fontsize)) text.textLine(element_text) pdf.drawText(text) # print "Word Dict" print word_dict # print "Word Array" # print word_array # pdf.textAnnotation(repr(word_array), name='word_array') # put the image on the page, scaled to fill the page if image_filename is not None: im = Image.open(image_filename) pdf.drawInlineImage(im, 0, 0, width=pt_page_width, height=pt_page_height) # finish up the page and save it pdf.showPage() pdf.save()
def to_pdf(self, imageFileName, outFileName, fontname="Courier", fontsize=8): """ Creates a PDF file with an image superimposed on top of the text. Text is positioned according to the bounding box of the lines in the hOCR file. The image need not be identical to the image used to create the hOCR file. It can be scaled, have a lower resolution, different color mode, etc. """ if self.hocr is None: # warn that no text will be embedded in the output PDF print "Warning: No hOCR file specified. PDF will be image-only." im = Image.open(imageFileName) imwidthpx, imheightpx = im.size if 'dpi' in im.info: width = float(im.size[0]) / im.info['dpi'][0] height = float(im.size[1]) / im.info['dpi'][1] else: # we have to make a reasonable guess # set to None for now and try again using info from hOCR file width = height = None ocr_dpi = (300, 300) # a default, in case we can't find it # get dimensions of the OCR, which may not match the image if self.hocr is not None: for div in self.hocr.findall(".//%sdiv" % (self.xmlns)): if div.attrib['class'] == 'ocr_page': coords = self.element_coordinates(div) ocrwidth = coords[2] - coords[0] ocrheight = coords[3] - coords[1] if width is None: # no dpi info with the image # assume OCR was done at 300 dpi width = ocrwidth / 300 height = ocrheight / 300 ocr_dpi = (ocrwidth / width, ocrheight / height) break # there shouldn't be more than one, and if there is, we don't want it if width is None: # no dpi info with the image, and no help from the hOCR file either # this will probably end up looking awful, so issue a warning print "Warning: DPI unavailable for image %s. Assuming 96 DPI." % ( imageFileName) width = float(im.size[0]) / 96 height = float(im.size[1]) / 96 # create the PDF file pdf = Canvas(outFileName, pagesize=(width * inch, height * inch), pageCompression=1) # page size in points (1/72 in.) # put the image on the page, scaled to fill the page pdf.drawInlineImage(im, 0, 0, width=width * inch, height=height * inch) if self.hocr is not None: for line in self.hocr.findall(".//%sspan" % (self.xmlns)): if line.attrib['class'] == 'ocr_line': coords = self.element_coordinates(line) text = pdf.beginText() text.setFont(fontname, fontsize) text.setTextRenderMode(3) # invisible # set cursor to bottom left corner of line bbox (adjust for dpi) text.setTextOrigin((float(coords[0]) / ocr_dpi[0]) * inch, (height * inch) - (float(coords[3]) / ocr_dpi[1]) * inch) # scale the width of the text to fill the width of the line's bbox text.setHorizScale( (((float(coords[2]) / ocr_dpi[0] * inch) - (float(coords[0]) / ocr_dpi[0] * inch)) / pdf.stringWidth(line.text.rstrip(), fontname, fontsize)) * 100) # write the text to the page text.textLine(line.text.rstrip()) pdf.drawText(text) # finish up the page and save it pdf.showPage() pdf.save()
class PDFGenerator(ReportGenerator): """This is a generator to output a PDF using ReportLab library with preference by its Platypus API""" filename = None _is_first_page = True _is_latest_page = True _current_top_position = 0 _current_page_number = 0 _current_object = None def __init__(self, report, filename): super(PDFGenerator, self).__init__(report) self.filename = filename def execute(self): """Generate a PDF file using ReportLab pdfgen package.""" # Initializes the PDF canvas self.start_pdf(self.filename) self.generate_pages() # Finalizes the canvas self.canvas.save() def start_pdf(self, filename): """Initializes the PDF document with some properties and methods""" # Sets the PDF canvas self.canvas = Canvas(filename=filename, pagesize=self.report.page_size) # Set PDF properties self.canvas.setTitle(self.report.title) self.canvas.setAuthor(self.report.author) self._is_first_page = True def generate_band(self, band, top_position=None): """Generate a band having the current top position or informed as its top coordinate""" # Coordinates and dimensions temp_top = top_position = top_position or self.get_top_pos() band_rect = { 'left': self.report.margin_left, 'top': top_position, 'right': self.report.page_size[0] - self.report.margin_right, 'bottom': top_position - band.height, } # This should be done by a metaclass in Report domain TODO band.width = self.report.page_size[ 0] - self.report.margin_left - self.report.margin_right # Loop at band widgets for element in band.elements: # Widget element if isinstance(element, Widget): widget = element # Set element colors self.set_fill_color(self.report.default_font_color) # Set widget basic attributes widget.instance = self._current_object widget.generator = self widget.report = self.report # This should be done by a metaclass in Band domain TODO widget.band = band # This should be done by a metaclass in Band domain TODO if isinstance(widget, Label): para = Paragraph( widget.text, ParagraphStyle(name='Normal', **widget.style)) para.wrapOn(self.canvas, widget.width, widget.height) para.drawOn(self.canvas, self.report.margin_left + widget.left, temp_top - widget.top - para.height) # Graphic element elif isinstance(element, Graphic): graphic = element # Set element colors self.set_fill_color(graphic.fill_color or self.report.default_fill_color) self.set_stroke_color(graphic.stroke_color or self.report.default_stroke_color) self.set_stroke_width(graphic.stroke_width) if isinstance(element, RoundRect): self.canvas.roundRect( self.report.margin_left + graphic.left, top_position - graphic.top - graphic.height, graphic.width, graphic.height, graphic.radius, graphic.stroke, graphic.fill, ) elif isinstance(element, Rect): self.canvas.rect( self.report.margin_left + graphic.left, top_position - graphic.top - graphic.height, graphic.width, graphic.height, graphic.stroke, graphic.fill, ) elif isinstance(element, Line): self.canvas.line( self.report.margin_left + graphic.left, top_position - graphic.top, self.report.margin_left + graphic.right, top_position - graphic.bottom, ) elif isinstance(element, Circle): self.canvas.circle( self.report.margin_left + graphic.left_center, top_position - graphic.top_center, graphic.radius, graphic.stroke, graphic.fill, ) elif isinstance(element, Arc): self.canvas.arc( self.report.margin_left + graphic.left, top_position - graphic.top, self.report.margin_left + graphic.right, top_position - graphic.bottom, graphic.start_angle, graphic.extent, ) elif isinstance(element, Ellipse): self.canvas.ellipse( self.report.margin_left + graphic.left, top_position - graphic.top, self.report.margin_left + graphic.right, top_position - graphic.bottom, graphic.stroke, graphic.fill, ) elif isinstance(element, Image): self.canvas.drawInlineImage( graphic.image, self.report.margin_left + graphic.left, top_position - graphic.top - graphic.height, graphic.width, graphic.height, ) # Band borders if band.borders.get('all', None): self.canvas.rect( band_rect['left'], band_rect['top'] - band.height, band_rect['right'] - band_rect['left'], band.height, ) if band.borders.get('top', None): self.canvas.line(band_rect['left'], band_rect['top'], band_rect['right'], band_rect['top']) if band.borders.get('right', None): self.canvas.line(band_rect['right'], band_rect['top'], band_rect['right'], band_rect['bottom']) if band.borders.get('bottom', None): self.canvas.line(band_rect['left'], band_rect['bottom'], band_rect['right'], band_rect['bottom']) if band.borders.get('left', None): self.canvas.line(band_rect['left'], band_rect['top'], band_rect['left'], band_rect['bottom']) def generate_begin(self): """Generate the report begin band if it exists""" if not self.report.band_begin: return # Call method that print the band area and its widgets self.generate_band(self.report.band_begin) # Update top position after this band self.update_top_pos(self.report.band_begin.height) def generate_summary(self): """Generate the report summary band if it exists""" if not self.report.band_summary: return # Check to force new page if there is no available space force_new_page = self.get_available_height( ) < self.report.band_summary.height if force_new_page: # Ends the current page self._current_top_position = 0 self.canvas.showPage() # Starts a new one self.start_new_page() # Call method that print the band area and its widgets self.generate_band(self.report.band_summary) if force_new_page: self.generate_page_footer() def generate_page_header(self): """Generate the report page header band if it exists""" if not self.report.band_page_header: return # Call method that print the band area and its widgets self.generate_band(self.report.band_page_header, self.report.page_size[1] - self.report.margin_top) def generate_page_footer(self): """Generate the report page footer band if it exists""" if not self.report.band_page_footer: return # Call method that print the band area and its widgets self.generate_band( self.report.band_page_footer, self.report.margin_bottom + self.report.band_page_footer.height, ) def generate_pages(self): """Loops into the queryset to create the report pages until the end""" # Preparing local auxiliar variables self._current_page_number = 0 self._current_object_index = 0 objects = self.report.queryset and \ [object for object in self.report.queryset] or\ [] # Empty report if self.report.print_if_empty and not objects: self.start_new_page() self.generate_begin() self.end_current_page() # Loop for pages while self._current_object_index < len(objects): # Starts a new page and generates the page header band self.start_new_page() # Generate the report begin band if self._current_page_number == 0: self.generate_begin() # Does generate objects if there is no details band if not self.report.band_detail: self._current_object_index = len(objects) # Loop for objects to go into grid on current page while self._current_object_index < len(objects): # Get current object from list self._current_object = objects[self._current_object_index] # Generates the detail band self.generate_band(self.report.band_detail) # Updates top position self.update_top_pos(self.report.band_detail.height) # Next object self._current_object_index += 1 # Break is this is the end of this page if self.get_available_height( ) < self.report.band_detail.height: break # Sets this is the latest page or not self._is_latest_page = self._current_object_index >= len(objects) # Ends the current page, printing footer and summary and necessary self.end_current_page() # Breaks if this is the latest item if self._is_latest_page: break # Increment page number self._current_page_number += 1 def start_new_page(self, with_header=True): """Do everything necessary to be done to start a new page""" if with_header: self.generate_page_header() def end_current_page(self): """Closes the current page, using showPage method. Everything done after this will draw into a new page. Before this, using the generate_page_footer method to draw the footer""" self.generate_page_footer() if self._is_latest_page: self.generate_summary() self.canvas.showPage() self._current_page_number += 1 self._is_first_page = False self.update_top_pos(set=0) # <---- update top position def get_top_pos(self): """Since the coordinates are bottom-left on PDF, we have to use this to get the current top position, considering also the top margin.""" ret = self.report.page_size[ 1] - self.report.margin_top - self._current_top_position if self.report.band_page_header: ret -= self.report.band_page_header.height return ret def get_available_height(self): """Returns the available client height area from the current top position until the end of page, considering the bottom margin.""" ret = self.report.page_size[1] - self.report.margin_bottom -\ self.report.margin_top - self._current_top_position if self.report.band_page_header: ret -= self.report.band_page_header.height if self.report.band_page_footer: ret -= self.report.band_page_footer.height return ret def update_top_pos(self, increase=0, decrease=0, set=None): """Updates the current top position controller, increasing (by default), decreasing or setting it with a new value.""" if set is not None: self._current_top_position = set else: self._current_top_position += increase self._current_top_position -= decrease return self._current_top_position def get_page_count(self): # TODO """Calculate and returns the page count for this report. The challenge here is do this calculate before to generate the pages.""" pass def set_fill_color(self, color): """Sets the current fill on canvas. Used for fonts and shape fills""" self.canvas.setFillColor(color) def set_stroke_color(self, color): """Sets the current stroke on canvas""" self.canvas.setStrokeColor(color) def set_stroke_width(self, width): """Sets the stroke/line width for shapes""" self.canvas.setLineWidth(width)
def to_pdf(self, out_filename, image_filename, show_bounding_boxes, hocr_file, dpi, font_name="Helvetica"): """ Creates a PDF file with an image superimposed on top of the text. Text is positioned according to the bounding box of the lines in the hOCR file. The image need not be identical to the image used to create the hOCR file. It can have a lower resolution, different color mode, etc. """ hocr_tree = etree.ElementTree() hocr_tree.parse(hocr_file) xmlns = self.lookup_namespace(hocr_tree) pt_page_height, pt_page_width = self.calculate_pt_dimensions(dpi, hocr_tree, xmlns) # no width and height definition in the ocr_image element of the hocr file if pt_page_width is None: print("No page dimension found in the hocr file") sys.exit(1) # Create the PDF file. Page size in points (1/72 in.) pdf = Canvas(out_filename, pagesize=(pt_page_width, pt_page_height), pageCompression=1) # draw bounding box for each paragraph green = Color(0.1, 0.5, 0.1) lime_green = Color(0.8, 1, 0) blue = Color(0, 1, 1) red = Color(1, 0, 0) black = Color(0, 0, 0) word_dict = dict() word_array = dict() paragraph_count = 0 for paragraph_element in hocr_tree.findall(".//%sp[@class='%s']" % (xmlns, "ocr_par")): element_text = self._get_element_text(paragraph_element).rstrip() if len(element_text) == 0: continue paragraph_count += 1 word_array[paragraph_count] = {} if show_bounding_boxes: x1, y1, x2, y2 = self.convert_px_coordinates_to_pt(self.element_coordinates(paragraph_element), dpi) self.draw_box(pdf, pt_page_height, x1, y1, x2, y2, lime_green, blue, is_filled=1, line_width=4) self.annotate_box(pdf, x1, pt_page_height - y1, 'p-%d_%s' % (paragraph_count, paragraph_element.get('id').rsplit('_', 1)[1])) line_count = 0 for line_element in paragraph_element.findall(".//%sspan[@class='%s']" % (xmlns, "ocr_line")): element_text = self._get_element_text(line_element).rstrip() if len(element_text) == 0: continue line_count += 1 word_array[paragraph_count][line_count] = {} if show_bounding_boxes: x1, y1, x2, y2 = self.convert_px_coordinates_to_pt(self.element_coordinates(line_element), dpi) self.draw_box(pdf, pt_page_height, x1, y1, x2, y2, green, blue, is_filled=1, line_width=1) self.annotate_box(pdf, x1, pt_page_height - y2, 'l-%d_%s' % (line_count, line_element.get('id').rsplit('_', 1)[1]), right_align=1) word_count = 0 for word_element in paragraph_element.findall(".//%sspan[@class='%s']" % (xmlns, "ocrx_word")): element_text = self._get_element_text(word_element).rstrip() element_text = self.replace_unsupported_chars(element_text) if len(element_text) == 0: continue word_count += 1 coordinates = self.element_coordinates(word_element) x1, y1, x2, y2 = HocrTransform2.convert_px_coordinates_to_pt(coordinates, dpi) # draw the bbox border if show_bounding_boxes: self.draw_box(pdf, pt_page_height, x1, y1, x2, y2, red, black, line_width=0.5, is_dashed=1) self.annotate_box(pdf, x1, pt_page_height - y1, 'w-%d' % word_count, top_align=1) # count_path = 'p(%d)l(%d)w(%d)' % (paragraph_count, line_count, word_count) # id_path = '%s %s %s' % (paragraph_element.get('id'), line_element.get('id'), word_element.get('id')) # print '%s] %s = "%s"' % (count_path, id_path, element_text) # word_dict[word_element.attrib['id']] = self._get_element_text(word_element) # print '%s="%s"' % (word_element.attrib['id'], word_dict[word_element.attrib['id']]) word_array[paragraph_count][line_count][word_count] = {'p': paragraph_count, 'l': line_count, 'w': word_count, 'id': word_element.attrib['id'], 'word': element_text, 'path': hocr_tree.getpath(word_element)} print word_array[paragraph_count][line_count][word_count] fontsize = self.px2pt(coordinates[3] - coordinates[1], dpi) pdf.setLineWidth(1) pdf.setDash([], 0) pdf.setStrokeColor(black) pdf.setFillColor(black) text = pdf.beginText() text.setTextRenderMode(0) text.setFont(font_name, fontsize) text.setTextOrigin(x1, pt_page_height - y2) text.setHorizScale(100 * (x2 - x1) / pdf.stringWidth(element_text, font_name, fontsize)) text.textLine(element_text) pdf.drawText(text) # print "Word Dict" print word_dict # print "Word Array" # print word_array #pdf.textAnnotation(repr(word_array), name='word_array') # put the image on the page, scaled to fill the page if image_filename is not None: im = Image.open(image_filename) pdf.drawInlineImage(im, 0, 0, width=pt_page_width, height=pt_page_height) # finish up the page and save it pdf.showPage() pdf.save()
def get(self, request, *args, **kwargs): self.object = self.get_object() response = HttpResponse(content_type='application/pdf') response[ 'Content-Disposition'] = 'attachment; filename="{0}-{1}.pdf"'.format( self.object.registru.serie, self.object.numar_inregistrare) pdf = Canvas(response, pagesize=A4) import os from reportlab.lib.styles import getSampleStyleSheet from reportlab.platypus import Paragraph pdfmetrics.registerFont( TTFont("DejaVuSans-Bold", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf")) pdfmetrics.registerFont( TTFont("DejaVuSans", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf")) if self.object.registru.centru_local.antet: antet_path = os.path.join( settings.MEDIA_ROOT, "%s" % self.object.registru.centru_local.antet) pdf.drawInlineImage(antet_path, 2.5 * cm, 10.8 * cm, width=16. * cm, height=2.66 * cm) pdf.drawInlineImage(antet_path, 2.5 * cm, 24.5 * cm, width=16. * cm, height=2.66 * cm) pdf.setStrokeColorRGB(0, 0, 0) pdf.rect(2. * cm, 2. * cm, 17. * cm, 12. * cm) pdf.rect(2. * cm, 15.7 * cm, 17. * cm, 12 * cm) pdf.setStrokeColorRGB(0.5, 0.5, 0.5) pdf.setDash(1, 2) pdf.line(0 * cm, 14.85 * cm, 21. * cm, 14.85 * cm) pdf.setFont("DejaVuSans-Bold", 0.5 * cm, leading=None) pdf.drawCentredString(10.5 * cm, 9.5 * cm, u"Chitanță") pdf.drawCentredString(10.5 * cm, 23.2 * cm, u"Chitanță") text_serie = u"seria {0}, nr. {1} / {2}".format( self.object.registru.serie, self.object.numar_inregistrare, self.object.data_inregistrare.strftime("%d.%m.%Y")) pdf.setFont("DejaVuSans-Bold", 4. * cm, leading=None) pdf.setFillColorRGB(0.95, 0.95, 0.95) pdf.rotate(15) pdf.drawString(4.5 * cm, 2. * cm, u"COPIE") pdf.rotate(-15) pdf.setFillColorRGB(0, 0, 0) pdf.setFont("DejaVuSans", 0.35 * cm, leading=None) pdf.drawCentredString(10.5 * cm, 8.9 * cm, text_serie) pdf.drawCentredString(10.5 * cm, 22.6 * cm, text_serie) reprezinta = self.object.descriere if hasattr(self.object, "chitantacotizatie"): reprezinta = [] for p in self.object.chitantacotizatie.platacotizatietrimestru_set.all( ).order_by("index"): date_reprezinta = (str(p.trimestru), p.suma, u"- parțial" if p.partial else "") reprezinta.append("{0} ({1} RON{2})".format(*date_reprezinta)) reprezinta = ", ".join(reprezinta) reprezinta = u"cotizație membru pentru {0}".format(reprezinta) date_chitanta = (str(self.object.platitor()), self.object.suma, suma2text(self.object.suma).strip(), reprezinta) text_chitanta = u"Am primit de la <strong>{0}</strong> suma de {1} lei, adică {2}, reprezentând {3}.".format( *date_chitanta) style_sheet = getSampleStyleSheet() style = style_sheet['Normal'] style.alignment = TA_JUSTIFY style.fontName = "DejaVuSans" style.leading = 0.85 * cm paragraph = Paragraph(text_chitanta, style) w, h = paragraph.wrap(15. * cm, 5. * cm) # print w, h paragraph.drawOn(pdf, 3. * cm, 5.5 * cm) paragraph.drawOn(pdf, 3. * cm, 19.2 * cm) pdf.drawString(12.5 * cm, 4.5 * cm, u"Casier,") pdf.drawString(12.5 * cm, 18.2 * cm, u"Casier, ") trezorier = self.object.registru.centru_local.ocupant_functie( u"Trezorier Centru Local") pdf.drawString(12.5 * cm, 3.8 * cm, str(trezorier)) pdf.drawString(12.5 * cm, 17.5 * cm, str(trezorier)) pdf.showPage() pdf.save() return response
SMALLFONTSIZE = 8 width, height = A4 centerh = height/2 # horizontal center, used to center text strings on the page # create the PDF --- DO NOT EDIT AFTER THIS LINE !!! --- pdf = Canvas("lipflyer.pdf") pdf.setPageSize([height, width]) # only trick I found to have a A4 in LANDSCAPE mode # Busy with "header" pdf.setTitle(TITLE) pdf.setSubject(SUBJECT) # pdf.setKeywords(KEYWORDS) # not working? pdf.setAuthor(AUTHOR) # Putting the 3 images pdf.drawInlineImage("images/tchantchux.jpg", 40, 240, width=158, height=283) pdf.drawImage("images/logo-lilit.png", 40, 40, width=None, height=None, mask=[255, 255, 255, 255, 226, 226]) pdf.drawInlineImage("images/penguin.png", 600, 250, width=217, height=260) # Putting the central text pdf.setFont(FONT, FONTSIZE) # xème journée d'installation de pdf.setFillColorRGB(255, 0, 0) chaine = NUMBER + " journée d'installation de" x = pdf.stringWidth(chaine, FONTBOLD, FONTSIZE) pdf.drawString(centerh - x/2, 530, chaine) xx = pdf.stringWidth(NUMBER, FONTBOLD, FONTSIZE) # superscript in the previous string pdf.setFont(FONT, FONTSIZE2) chaine = "ème" pdf.drawString(centerh - x/2 + xx, 540, chaine) pdf.setFont(FONTBOLD, FONTSIZE) # GNU/Linux pdf.setFillColorRGB(0, 0, 0) chaine = "GNU/Linux"
def to_pdf(self, imageFileNames, outFileName, fontname="Courier", fontsize=8, withVisibleOCRText=False, withVisibleImage=True, withVisibleBoundingBoxes=False, noPictureFromHocr=False, multiplePages=False, hocrImageReference=False, verticalInversion=False ): """ Creates a PDF file with an image superimposed on top of the text. Text is positioned according to the bounding box of the lines in the hOCR file. The image need not be identical to the image used to create the hOCR file. It can be scaled, have a lower resolution, different color mode, etc. """ # create the PDF file pdf = Canvas(outFileName, pageCompression=1) if self.hocr is None: # warn that no text will be embedded in the output PDF vprint( WARN, "Warning: No hOCR file specified. PDF will be image-only." ) # Collect pages from hOCR pages = [] if self.hocr is not None: divs = self.hocr.findall(".//%sdiv"%(self.xmlns)) for div in divs: if div.attrib['class'] == 'ocr_page': pages.append(div) vprint( VVERBOSE, len(pages), "pages;", len(imageFileNames), "image files from command line." ) page_count = 0 # loop pages while True: page_count += 1 vprint( VERBOSE, "page", page_count ) if len(pages) >= page_count: page = pages[page_count-1] else: page = None if page_count > 1: if not multiplePages: vprint (INFO, "Only processing one page." ) break # there shouldn't be more than one, and if there is, we don't want it imageFileName = None # Check for image from command line if imageFileNames: # distinct file if len(imageFileNames) >= page_count: imageFileName = imageFileNames[page_count-1] # repeat the last file else: imageFileName = imageFileNames[-1] # stop if no more ocr date if page == None: break else: if page == None: break vprint ( VERBOSE, "Image file name:", imageFileName ) vprint ( VERBOSE, "page:", page.tag, page.attrib ) # Dimensions of ocr-page if page is not None: coords = self.element_coordinates( page ) else: coords = (0,0,0,0) ocrwidth = coords[2]-coords[0] ocrheight = coords[3]-coords[1] # Load command line image if imageFileName: im, width, height = self._setup_image(imageFileName) vprint( VVERBOSE, "width, heigth:", width, height ) else: im = width = height = None # Image from hOCR # get dimensions, which may not match the image im_ocr = None if page is not None: parse_result = self.parse_element_title( page ) vprint( VVERBOSE, "ocr_page file ?" ) vprint( VVERBOSE, "Parse Results:",parse_result ) if parse_result.has_key( "file" ): imageFileName_ocr_page = parse_result["file"] vprint( VERBOSE, "ocr_page file", imageFileName_ocr_page, nolinebreak=True ) if noPictureFromHocr: vprint( VERBOSE, "- ignored.", nolinebreak=True ) if imageFileName: vprint( VERBOSE, "- ignored (overwritten by command line).", nolinebreak=True ) vprint( VERBOSE, "" ) if ( ( not noPictureFromHocr ) and ( not imageFileName) ) or hocrImageReference: im_ocr, width_ocr, height_ocr = self._setup_image(imageFileName_ocr_page) vprint( VERBOSE, "hOCR width, heigth:", width, height ) if ( not noPictureFromHocr ) and ( not imageFileName): im = im_ocr width = width_ocr height = height_ocr # Get size of text area in hOCR-file ocr_text_x_min, ocr_text_y_min, ocr_text_x_max, ocr_text_y_max = self.get_ocr_text_extension( page ) ocr_text_width = ocr_text_x_max ocr_text_height = ocr_text_y_max if not ocrwidth: if im_ocr: ocrwidth = im_ocr.size[0] else: ocrwidth = ocr_text_width if not ocrheight: if im_ocr: ocrheight = im_ocr.size[1] else: ocrheight = ocr_text_height vprint( VERBOSE, "ocrwidth, ocrheight :", ocrwidth, ocrheight ) if ( ( not ocrwidth ) and ( ( not width ) or ( not withVisibleImage ) ) ) or ( ( not ocrheight) and ( ( not height ) or ( not withVisibleImage ) ) ): vprint( WARN, "Page with extension 0 or without content. Skipping." ) else: if page is not None: ocr_dpi = (300, 300) # a default, in case we can't find it if width is None: # no dpi info with the image # assume OCR was done at 300 dpi width = ocrwidth / 300.0 height = ocrheight / 300.0 vprint( VERBOSE, "Assuming width, height:",width,height ) ocr_dpi = (ocrwidth/width, ocrheight/height) vprint( VERBOSE, "ocr_dpi :", ocr_dpi ) if width is None: # no dpi info with the image, and no help from the hOCR file either # this will probably end up looking awful, so issue a warning vprint( WARN, "Warning: DPI unavailable for image %s. Assuming 96 DPI."%(imageFileName) ) width = float(im.size[0])/96 height = float(im.size[1])/96 # PDF page size pdf.setPageSize((width*inch, height*inch)) # page size in points (1/72 in.) # put the image on the page, scaled to fill the page if withVisibleImage: if im: pdf.drawInlineImage(im, 0, 0, width=width*inch, height=height*inch) else: vprint( INFO, "No inline image file supplied." ) # put ocr-content on the page if self.hocr is not None: text_elements = self.getTextElements( page ) for line in text_elements: import pdb vprint( VVERBOSE, line.tag, line.attrib ) if line.attrib.has_key('class'): text_class = line.attrib['class'] else: text_class = None if text_class in [ 'ocr_line', 'ocrx_word', 'ocr_carea', 'ocr_par' ]: if text_class == 'ocr_line': textColor = (255,0,0) bboxColor = (0,255,0) elif text_class == 'ocrx_word' : textColor = (255,0,0) bboxColor = (0,255,255) elif text_class == 'ocr_carea' : textColor = (255,0,0) bboxColor = (255,255,0) elif text_class == 'ocr_par' : textColor = (255,0,0) bboxColor = (255,0,0) coords = self.element_coordinates( line ) parse_result = self.parse_element_title( line ) text = pdf.beginText() text.setFont(fontname, fontsize) text_corner1x = (float(coords[0])/ocr_dpi[0])*inch text_corner1y = (float(coords[1])/ocr_dpi[1])*inch text_corner2x = (float(coords[2])/ocr_dpi[0])*inch text_corner2y = (float(coords[3])/ocr_dpi[1])*inch text_width = text_corner2x - text_corner1x text_height = text_corner2y - text_corner1y if verticalInversion: text_corner2y_inv = (height*inch) - text_corner1y text_corner1y_inv = (height*inch) - text_corner2y text_corner1y = text_corner1y_inv text_corner2y = text_corner2y_inv # set cursor to bottom left corner of line bbox (adjust for dpi) text.setTextOrigin( text_corner1x, text_corner1y ) # The content of the text to write textContent = line.text if ( textContent == None ): textContent = u"" textContent = textContent.rstrip() # scale the width of the text to fill the width of the line's bbox if len(textContent) != 0: text.setHorizScale( ((( float(coords[2])/ocr_dpi[0]*inch ) - ( float(coords[0])/ocr_dpi[0]*inch )) / pdf.stringWidth( textContent, fontname, fontsize))*100) if not withVisibleOCRText: text.setTextRenderMode(3) # invisible # Text color text.setFillColorRGB(textColor[0],textColor[1],textColor[2]) # write the text to the page text.textLine( textContent ) vprint( VVERBOSE, "processing", text_class, coords,"->", text_corner1x, text_corner1y, text_corner2x, text_corner2y, ":", textContent ) pdf.drawText(text) pdf.setLineWidth(0.1) pdf.setStrokeColorRGB(bboxColor[0],bboxColor[1],bboxColor[2]) # Draw a box around the text object if withVisibleBoundingBoxes: pdf.rect( text_corner1x, text_corner1y, text_width, text_height); # finish up the page. A blank new one is initialized as well. pdf.showPage() # save the pdf file vprint( INFO, "Writing pdf." ) pdf.save()
width, height = A4 centerh = height / 2 # horizontal center, used to center text strings on the page # create the PDF --- DO NOT EDIT AFTER THIS LINE !!! --- pdf = Canvas("lipflyer.pdf") pdf.setPageSize([height, width]) # only trick I found to have a A4 in LANDSCAPE mode # Busy with "header" pdf.setTitle(TITLE) pdf.setSubject(SUBJECT) # pdf.setKeywords(KEYWORDS) # not working? pdf.setAuthor(AUTHOR) # Putting the 3 images pdf.drawInlineImage("images/tchantchux.jpg", 40, 240, width=158, height=283) pdf.drawImage("images/logo-lilit.png", 40, 40, width=None, height=None, mask=[255, 255, 255, 255, 226, 226]) pdf.drawInlineImage("images/penguin.png", 600, 250, width=217, height=260) # Putting the central text pdf.setFont(FONT, FONTSIZE) # xème journée d'installation de pdf.setFillColorRGB(255, 0, 0) chaine = NUMBER + " journée d'installation de" x = pdf.stringWidth(chaine, FONTBOLD, FONTSIZE) pdf.drawString(centerh - x / 2, 530, chaine) xx = pdf.stringWidth(NUMBER, FONTBOLD, FONTSIZE) # superscript in the previous string
serials.append(serial); # Writing text coords = card(x, y) pdf.setFont("Helvetica", URLSIZE) px = coords[0] + URLOFFSET[0] py = coords[1] + URLOFFSET[1] pdf.drawString(px, py, URL) pdf.setFont("Helvetica", SERIALSIZE) px = coords[0] + SERIALOFFSET[0] py = coords[1] + SERIALOFFSET[1] pdf.drawString(px, py, serial) # Generating and writing the QR code os.system("qrencode -o .tempqr.png -s 30 -m 0 -l H " + serial) px = coords[0] + QROFFSET[0]; py = coords[1] + QROFFSET[1] pdf.drawInlineImage(".tempqr.png", px, py, width=QRSIZE, height=QRSIZE) os.remove(".tempqr.png") # Closing the page pdf.showPage() pdf.save()
def to_pdf(self, outFileName, imageFileName, showBoundingboxes, fontname="Helvetica"): """ Creates a PDF file with an image superimposed on top of the text. Text is positioned according to the bounding box of the lines in the hOCR file. The image need not be identical to the image used to create the hOCR file. It can have a lower resolution, different color mode, etc. """ # create the PDF file pdf = Canvas(outFileName, pagesize=(self.width, self.height), pageCompression=1) # page size in points (1/72 in.) # draw bounding box for each paragraph pdf.setStrokeColorRGB(0,1,1) # light blue for bounding box of paragraph pdf.setFillColorRGB(0,1,1) # light blue for bounding box of paragraph pdf.setLineWidth(0) # no line for bounding box for elem in self.hocr.findall(".//%sp[@class='%s']" % (self.xmlns, "ocr_par")): elemtxt=self._get_element_text(elem).rstrip() if len(elemtxt) == 0: continue coords = self.element_coordinates(elem) x1=self.px2pt(coords[0]) y1=self.px2pt(coords[1]) x2=self.px2pt(coords[2]) y2=self.px2pt(coords[3]) # draw the bbox border if showBoundingboxes == True: pdf.rect(x1, self.height-y2, x2-x1, y2-y1, fill=1) # check if element with class 'ocrx_word' are available # otherwise use 'ocr_line' as fallback elemclass="ocr_line" if self.hocr.find(".//%sspan[@class='ocrx_word']" %(self.xmlns)) is not None: elemclass="ocrx_word" # itterate all text elements pdf.setStrokeColorRGB(1,0,0) # light green for bounding box of word/line pdf.setLineWidth(0.5) # bounding box line width pdf.setDash(6,3) # bounding box is dashed pdf.setFillColorRGB(0,0,0) # text in black for elem in self.hocr.findall(".//%sspan[@class='%s']" % (self.xmlns, elemclass)): elemtxt=self._get_element_text(elem).rstrip() elemtxt=self.replace_unsupported_chars(elemtxt) if len(elemtxt) == 0: continue coords = self.element_coordinates(elem) x1=self.px2pt(coords[0]) y1=self.px2pt(coords[1]) x2=self.px2pt(coords[2]) y2=self.px2pt(coords[3]) # draw the bbox border if showBoundingboxes == True: pdf.rect(x1, self.height-y2, x2-x1, y2-y1, fill=0) text = pdf.beginText() fontsize=self.px2pt(coords[3]-coords[1]) text.setFont(fontname, fontsize) # set cursor to bottom left corner of bbox (adjust for dpi) text.setTextOrigin(x1, self.height-y2) # scale the width of the text to fill the width of the bbox text.setHorizScale(100*(x2-x1)/pdf.stringWidth(elemtxt, fontname, fontsize)) # write the text to the page text.textLine(elemtxt) pdf.drawText(text) # put the image on the page, scaled to fill the page if imageFileName != None: im = Image.open(imageFileName) pdf.drawInlineImage(im, 0, 0, width=self.width, height=self.height) # finish up the page and save it pdf.showPage() pdf.save()
def createCardReport(fileName): global currentCard, questions, aChoices, bChoices, cChoices, tChoices, fChoices, answers questionCards = ReportPage(fileName + "_questions.pdf", pagesize=letter) xOffset = 25 * mm yOffset = 12 * mm card = 0 for y in range(4, -1, -1): for x in range(0, 2, 1): firstLinePos = 40 * mm xPos = x * (89 * mm) + xOffset yPos = y * (51 * mm) + yOffset # Draw the question. style = ParagraphStyle('Bigger') style.fontSize = 12 question = Paragraph(questions[card], style) aW = 70 * mm # available width and height aH = 20 * mm _, h = question.wrap(aW, aH) firstLinePos -= h question.drawOn(questionCards, xPos, yPos + firstLinePos) firstLinePos -= 10 * mm xPos += 15 * mm # Process the choices. choice = aChoices[card] if choice != "": questionCards.drawString(xPos, yPos + firstLinePos, "a. " + choice) firstLinePos -= 6 * mm choice = bChoices[card] if choice != "": questionCards.drawString(xPos, yPos + firstLinePos, "b. " + choice) firstLinePos -= 6 * mm choice = cChoices[card] if choice != "": questionCards.drawString(xPos, yPos + firstLinePos, "c. " + choice) firstLinePos -= 6 * mm choice = tChoices[card] if choice != "": questionCards.drawString(xPos, yPos + firstLinePos, "t. " + choice) firstLinePos -= 6 * mm elif answers[card] == 4 or answers[card] == 5: questionCards.drawString(xPos, yPos + firstLinePos, "True") firstLinePos -= 6 * mm choice = fChoices[card] if choice != "": questionCards.drawString(xPos, yPos + firstLinePos, "f. " + choice) elif answers[card] == 4 or answers[card] == 5: questionCards.drawString(xPos, yPos + firstLinePos, "False") card += 1 questionCards.save() answerCards = ReportPage(fileName + "_answers.pdf", pagesize=letter) xOffset = 32 * mm yOffset = 15 * mm card = 0 for y in range(4, -1, -1): for x in range(1, -1, -1): xPos = x * (89 * mm) + xOffset yPos = y * (51 * mm) + yOffset answerCards.drawInlineImage( getCode(answers[card]) + " QR Code.png", xPos, yPos, 50 * mm, 50 * mm) card += 1 answerCards.save()
def _draw_page_list(page_list, output_buffer=None, username=None, title=None, view_type=None): """ Draw a list of pages into a pdf file. """ if output_buffer is None: output_buffer = StringIO() canvas = Canvas(output_buffer) if username is not None: canvas.setAuthor(username) if title is not None: canvas.setTitle(title) if view_type is None: view_type = AssetClass.PAGE_IMAGE view_asset_class = AssetClass.objects.get(name=view_type) text_asset_class = AssetClass.objects.get(name=AssetClass.PAGE_TEXT) for page in page_list: # For each page, get S3 URL for an image and HTML representation # extract text from the HTML # put image and text into PDF canvas # NB Image.open seems to only work with a file (not a stream) # so we have to create (and delete) a temporary file that # holds the image and the text image_stream = StringIO() image_asset = page.get_asset(view_asset_class) image_file = instantiate_asset(image_asset)['Local-Path'] image = Image.open(image_file) text_asset = page.get_asset(text_asset_class) text_file = instantiate_asset(text_asset)['Local-Path'] text = open(text_file, 'r').read() image_width, image_heigth, text_fragments = misc.extract_text_from_hocr( text) w = (image_width / DPI) * inch h = (image_heigth / DPI) * inch rw = w / image_width rh = h / image_heigth for fragment in text_fragments: canvas.drawString(rw * fragment['x'], h - rh * fragment['y'], fragment['text']) canvas.drawInlineImage(image, 0, 0, w, h) canvas.setPageSize((w, h)) canvas.showPage() os.remove(image_file) os.remove(text_file) canvas.save() return output_buffer
def to_pdf(self, imageFileName, outFileName, fontname="Times-Roman", fontsize=10, withVisibleOCRText=False, withVisibleImage=True, withVisibleBoundingBoxes=False): """ Creates a PDF file with an image superimposed on top of the text. Text is positioned according to the bounding box of the lines in the hOCR file. The image need not be identical to the image used to create the hOCR file. It can be scaled, have a lower resolution, different color mode, etc. """ if self.hocr is None: # warn that no text will be embedded in the output PDF print "Warning: No hOCR file specified. PDF will be image-only." im = Image.open(imageFileName) imwidthpx, imheightpx = im.size if 'dpi' in im.info: width = float(im.size[0])/im.info['dpi'][0] height = float(im.size[1])/im.info['dpi'][1] else: # we have to make a reasonable guess # set to None for now and try again using info from hOCR file width = height = None ocr_dpi = (300, 300) # a default, in case we can't find it # get dimensions of the OCR, which may not match the image if self.hocr is not None: for div in self.hocr.findall(".//%sdiv"%(self.xmlns)): if div.attrib['class'] == 'ocr_page': coords = self.element_coordinates(div) ocrwidth = coords[2]-coords[0] ocrheight = coords[3]-coords[1] if width is None: # no dpi info with the image # assume OCR was done at 300 dpi width = ocrwidth/300 height = ocrheight/300 ocr_dpi = (ocrwidth/width, ocrheight/height) break # there shouldn't be more than one, and if there is, we don't want it if width is None: # no dpi info with the image, and no help from the hOCR file either # this will probably end up looking awful, so issue a warning print "Warning: DPI unavailable for image %s. Assuming 96 DPI."%(imageFileName) width = float(im.size[0])/96 height = float(im.size[1])/96 # create the PDF file pdf = Canvas(outFileName, pagesize=(width*inch, height*inch), pageCompression=1) # page size in points (1/72 in.) # put the image on the page, scaled to fill the page if withVisibleImage: pdf.drawInlineImage(im, 0, 0, width=width*inch, height=height*inch) if self.hocr is not None: for word in self.hocr.findall(".//%sspan"%(self.xmlns)): if word.attrib['class'] == 'ocr_word': coords = self.element_coordinates(word) content = self._get_element_text(word) if content.rstrip() == '': continue text = pdf.beginText() text.setFont(fontname, fontsize) if not withVisibleOCRText: #text.setTextRenderMode(0) # visible #else: text.setTextRenderMode(3) # invisible # set cursor to bottom left corner of line bbox (adjust for dpi) # Can't determine original text's baseline, but guess that ypg # roughly push it down by ~2/3 of line height. Correct for that. # PDF y coords increase going *up* the page, remember. Assume "o" is # round so width == line height. origin_y = (height*inch)-(float(coords[3])/ocr_dpi[1])*inch if re.search(r"[gjpqy()]", content): origin_y += pdf.stringWidth("o") * 1/3 if re.search(r"[\[\]()]", content): origin_y += pdf.stringWidth("o") * 1/3.5 elif re.search(r"[,;]", content): origin_y += pdf.stringWidth("o") * 1/4 text.setTextOrigin((float(coords[0])/ocr_dpi[0])*inch, origin_y) # scale the width of the text to fill the width of the line's bbox text.setHorizScale((((float(coords[2])/ocr_dpi[0]*inch)-(float(coords[0])/ocr_dpi[0]*inch))/pdf.stringWidth(content.rstrip(), fontname, fontsize))*100) # write the text to the page text.textLine(content.rstrip()) pdf.drawText(text) # finish up the page and save it pdf.showPage() pdf.save()
def to_pdf(self, outFileName, imageFileName, showBoundingboxes, fontname="Helvetica"): """ Creates a PDF file with an image superimposed on top of the text. Text is positioned according to the bounding box of the lines in the hOCR file. The image need not be identical to the image used to create the hOCR file. It can have a lower resolution, different color mode, etc. """ # create the PDF file pdf = Canvas(outFileName, pagesize=(self.width, self.height), pageCompression=1) # page size in points (1/72 in.) # draw bounding box for each paragraph pdf.setStrokeColorRGB(0, 1, 1) # light blue for bounding box of paragraph pdf.setFillColorRGB(0, 1, 1) # light blue for bounding box of paragraph pdf.setLineWidth(0) # no line for bounding box for elem in self.hocr.findall(".//%sp[@class='%s']" % (self.xmlns, "ocr_par")): elemtxt = self._get_element_text(elem).rstrip() if len(elemtxt) == 0: continue coords = self.element_coordinates(elem) x1 = self.px2pt(coords[0]) y1 = self.px2pt(coords[1]) x2 = self.px2pt(coords[2]) y2 = self.px2pt(coords[3]) # draw the bbox border if showBoundingboxes == True: pdf.rect(x1, self.height - y2, x2 - x1, y2 - y1, fill=1) # check if element with class 'ocrx_word' are available # otherwise use 'ocr_line' as fallback elemclass = "ocr_line" if self.hocr.find(".//%sspan[@class='ocrx_word']" % (self.xmlns)) is not None: elemclass = "ocrx_word" # itterate all text elements pdf.setStrokeColorRGB(1, 0, 0) # light green for bounding box of word/line pdf.setLineWidth(0.5) # bounding box line width pdf.setDash(6, 3) # bounding box is dashed pdf.setFillColorRGB(0, 0, 0) # text in black for elem in self.hocr.findall(".//%sspan[@class='%s']" % (self.xmlns, elemclass)): elemtxt = self._get_element_text(elem).rstrip() elemtxt = self.replace_unsupported_chars(elemtxt) if len(elemtxt) == 0: continue coords = self.element_coordinates(elem) x1 = self.px2pt(coords[0]) y1 = self.px2pt(coords[1]) x2 = self.px2pt(coords[2]) y2 = self.px2pt(coords[3]) # draw the bbox border if showBoundingboxes == True: pdf.rect(x1, self.height - y2, x2 - x1, y2 - y1, fill=0) text = pdf.beginText() fontsize = self.px2pt(coords[3] - coords[1]) text.setFont(fontname, fontsize) # set cursor to bottom left corner of bbox (adjust for dpi) text.setTextOrigin(x1, self.height - y2) # scale the width of the text to fill the width of the bbox text.setHorizScale(100 * (x2 - x1) / pdf.stringWidth(elemtxt, fontname, fontsize)) # write the text to the page text.textLine(elemtxt) pdf.drawText(text) # put the image on the page, scaled to fill the page if imageFileName != None: im = Image.open(imageFileName) pdf.drawInlineImage(im, 0, 0, width=self.width, height=self.height) # finish up the page and save it pdf.showPage() pdf.save()
def _draw_page_list(page_list, output_buffer = None, username = None, title = None, view_type = None): """ Draw a list of pages into a pdf file. """ if output_buffer is None: output_buffer = StringIO() canvas = Canvas(output_buffer) if username is not None: canvas.setAuthor(username) if title is not None: canvas.setTitle(title) if view_type is None: view_type = AssetClass.PAGE_IMAGE view_asset_class = AssetClass.objects.get(name = view_type) text_asset_class = AssetClass.objects.get(name = AssetClass.PAGE_TEXT) for page in page_list: # For each page, get S3 URL for an image and HTML representation # extract text from the HTML # put image and text into PDF canvas # NB Image.open seems to only work with a file (not a stream) # so we have to create (and delete) a temporary file that # holds the image and the text image_stream = StringIO() image_asset = page.get_asset(view_asset_class) image_file = instantiate_asset(image_asset)['Local-Path'] image = Image.open(image_file) text_asset = page.get_asset(text_asset_class) text_file = instantiate_asset(text_asset)['Local-Path'] text = open(text_file,'r').read() image_width, image_heigth, text_fragments = misc.extract_text_from_hocr(text) w = (image_width/DPI)*inch h = (image_heigth/DPI)*inch rw = w/image_width rh = h/image_heigth for fragment in text_fragments: canvas.drawString(rw * fragment['x'], h - rh *fragment['y'], fragment['text']) canvas.drawInlineImage( image, 0, 0, w, h) canvas.setPageSize((w,h)) canvas.showPage() os.remove(image_file) os.remove(text_file) canvas.save() return output_buffer
class PDFGenerator(ReportGenerator): """This is a generator to output a PDF using ReportLab library with preference by its Platypus API""" filename = None _is_first_page = True _is_latest_page = True _current_top_position = 0 _current_page_number = 0 _current_object = None def __init__(self, report, filename): super(PDFGenerator, self).__init__(report) self.filename = filename def execute(self): """Generate a PDF file using ReportLab pdfgen package.""" # Initializes the PDF canvas self.start_pdf(self.filename) self.generate_pages() # Finalizes the canvas self.canvas.save() def start_pdf(self, filename): """Initializes the PDF document with some properties and methods""" # Sets the PDF canvas self.canvas = Canvas(filename=filename, pagesize=self.report.page_size) # Set PDF properties self.canvas.setTitle(self.report.title) self.canvas.setAuthor(self.report.author) self._is_first_page = True def generate_band(self, band, top_position=None): """Generate a band having the current top position or informed as its top coordinate""" # Coordinates and dimensions temp_top = top_position = top_position or self.get_top_pos() band_rect = { 'left': self.report.margin_left, 'top': top_position, 'right': self.report.page_size[0] - self.report.margin_right, 'bottom': top_position - band.height, } # This should be done by a metaclass in Report domain TODO band.width = self.report.page_size[0] - self.report.margin_left - self.report.margin_right # Loop at band widgets for element in band.elements: # Widget element if isinstance(element, Widget): widget = element # Set element colors self.set_fill_color(self.report.default_font_color) # Set widget basic attributes widget.instance = self._current_object widget.generator = self widget.report = self.report # This should be done by a metaclass in Band domain TODO widget.band = band # This should be done by a metaclass in Band domain TODO if isinstance(widget, Label): para = Paragraph(widget.text, ParagraphStyle(name='Normal', **widget.style)) para.wrapOn(self.canvas, widget.width, widget.height) para.drawOn(self.canvas, self.report.margin_left + widget.left, temp_top - widget.top - para.height) # Graphic element elif isinstance(element, Graphic): graphic = element # Set element colors self.set_fill_color(graphic.fill_color or self.report.default_fill_color) self.set_stroke_color(graphic.stroke_color or self.report.default_stroke_color) self.set_stroke_width(graphic.stroke_width) if isinstance(element, RoundRect): self.canvas.roundRect( self.report.margin_left + graphic.left, top_position - graphic.top - graphic.height, graphic.width, graphic.height, graphic.radius, graphic.stroke, graphic.fill, ) elif isinstance(element, Rect): self.canvas.rect( self.report.margin_left + graphic.left, top_position - graphic.top - graphic.height, graphic.width, graphic.height, graphic.stroke, graphic.fill, ) elif isinstance(element, Line): self.canvas.line( self.report.margin_left + graphic.left, top_position - graphic.top, self.report.margin_left + graphic.right, top_position - graphic.bottom, ) elif isinstance(element, Circle): self.canvas.circle( self.report.margin_left + graphic.left_center, top_position - graphic.top_center, graphic.radius, graphic.stroke, graphic.fill, ) elif isinstance(element, Arc): self.canvas.arc( self.report.margin_left + graphic.left, top_position - graphic.top, self.report.margin_left + graphic.right, top_position - graphic.bottom, graphic.start_angle, graphic.extent, ) elif isinstance(element, Ellipse): self.canvas.ellipse( self.report.margin_left + graphic.left, top_position - graphic.top, self.report.margin_left + graphic.right, top_position - graphic.bottom, graphic.stroke, graphic.fill, ) elif isinstance(element, Image): self.canvas.drawInlineImage( graphic.image, self.report.margin_left + graphic.left, top_position - graphic.top - graphic.height, graphic.width, graphic.height, ) # Band borders if band.borders.get('all', None): self.canvas.rect( band_rect['left'], band_rect['top'] - band.height, band_rect['right'] - band_rect['left'], band.height, ) if band.borders.get('top', None): self.canvas.line(band_rect['left'], band_rect['top'], band_rect['right'], band_rect['top']) if band.borders.get('right', None): self.canvas.line(band_rect['right'], band_rect['top'], band_rect['right'], band_rect['bottom']) if band.borders.get('bottom', None): self.canvas.line(band_rect['left'], band_rect['bottom'], band_rect['right'], band_rect['bottom']) if band.borders.get('left', None): self.canvas.line(band_rect['left'], band_rect['top'], band_rect['left'], band_rect['bottom']) def generate_begin(self): """Generate the report begin band if it exists""" if not self.report.band_begin: return # Call method that print the band area and its widgets self.generate_band(self.report.band_begin) # Update top position after this band self.update_top_pos(self.report.band_begin.height) def generate_summary(self): """Generate the report summary band if it exists""" if not self.report.band_summary: return # Check to force new page if there is no available space force_new_page = self.get_available_height() < self.report.band_summary.height if force_new_page: # Ends the current page self._current_top_position = 0 self.canvas.showPage() # Starts a new one self.start_new_page() # Call method that print the band area and its widgets self.generate_band(self.report.band_summary) if force_new_page: self.generate_page_footer() def generate_page_header(self): """Generate the report page header band if it exists""" if not self.report.band_page_header: return # Call method that print the band area and its widgets self.generate_band( self.report.band_page_header, self.report.page_size[1] - self.report.margin_top ) def generate_page_footer(self): """Generate the report page footer band if it exists""" if not self.report.band_page_footer: return # Call method that print the band area and its widgets self.generate_band( self.report.band_page_footer, self.report.margin_bottom + self.report.band_page_footer.height, ) def generate_pages(self): """Loops into the queryset to create the report pages until the end""" # Preparing local auxiliar variables self._current_page_number = 0 self._current_object_index = 0 objects = self.report.queryset and \ [object for object in self.report.queryset] or\ [] # Empty report if self.report.print_if_empty and not objects: self.start_new_page() self.generate_begin() self.end_current_page() # Loop for pages while self._current_object_index < len(objects): # Starts a new page and generates the page header band self.start_new_page() # Generate the report begin band if self._current_page_number == 0: self.generate_begin() # Does generate objects if there is no details band if not self.report.band_detail: self._current_object_index = len(objects) # Loop for objects to go into grid on current page while self._current_object_index < len(objects): # Get current object from list self._current_object = objects[self._current_object_index] # Generates the detail band self.generate_band(self.report.band_detail) # Updates top position self.update_top_pos(self.report.band_detail.height) # Next object self._current_object_index += 1 # Break is this is the end of this page if self.get_available_height() < self.report.band_detail.height: break # Sets this is the latest page or not self._is_latest_page = self._current_object_index >= len(objects) # Ends the current page, printing footer and summary and necessary self.end_current_page() # Breaks if this is the latest item if self._is_latest_page: break # Increment page number self._current_page_number += 1 def start_new_page(self, with_header=True): """Do everything necessary to be done to start a new page""" if with_header: self.generate_page_header() def end_current_page(self): """Closes the current page, using showPage method. Everything done after this will draw into a new page. Before this, using the generate_page_footer method to draw the footer""" self.generate_page_footer() if self._is_latest_page: self.generate_summary() self.canvas.showPage() self._current_page_number += 1 self._is_first_page = False self.update_top_pos(set=0) # <---- update top position def get_top_pos(self): """Since the coordinates are bottom-left on PDF, we have to use this to get the current top position, considering also the top margin.""" ret = self.report.page_size[1] - self.report.margin_top - self._current_top_position if self.report.band_page_header: ret -= self.report.band_page_header.height return ret def get_available_height(self): """Returns the available client height area from the current top position until the end of page, considering the bottom margin.""" ret = self.report.page_size[1] - self.report.margin_bottom -\ self.report.margin_top - self._current_top_position if self.report.band_page_header: ret -= self.report.band_page_header.height if self.report.band_page_footer: ret -= self.report.band_page_footer.height return ret def update_top_pos(self, increase=0, decrease=0, set=None): """Updates the current top position controller, increasing (by default), decreasing or setting it with a new value.""" if set is not None: self._current_top_position = set else: self._current_top_position += increase self._current_top_position -= decrease return self._current_top_position def get_page_count(self): # TODO """Calculate and returns the page count for this report. The challenge here is do this calculate before to generate the pages.""" pass def set_fill_color(self, color): """Sets the current fill on canvas. Used for fonts and shape fills""" self.canvas.setFillColor(color) def set_stroke_color(self, color): """Sets the current stroke on canvas""" self.canvas.setStrokeColor(color) def set_stroke_width(self, width): """Sets the stroke/line width for shapes""" self.canvas.setLineWidth(width)
class Reporter(object): def __init__(self,vapp): self.dataApp = vapp path = self.dataApp.repoPath + self.dataApp.rdataName + '.pdf' self.canvas = Canvas(path) self.page = 1 def header(self): self.canvas.setFont("Helvetica", 10) self.canvas.drawCentredString(4.135*inch, 10.74*inch, 'Copyright@2015 : ycroft.net') self.canvas.setFont("Helvetica", 11.5) self.canvas.line(1*inch, 10.69*inch, 7.27*inch, 10.69*inch) def footer(self): self.canvas.setFont("Helvetica", 11.5) self.canvas.line(1*inch, 1*inch, 7.27*inch, 1*inch) self.canvas.setFont("Helvetica", 10) self.canvas.drawCentredString(4.135*inch, 0.83*inch, '- '+str(self.page)+' -') def cover(self,coverInfo): dataName = coverInfo.get('dataName','no name') author = coverInfo.get('author','no name') version = coverInfo.get('version','unknown') self.header() self.footer() self.canvas.setFont("Helvetica-Bold", 40) self.canvas.drawCentredString(4.135*inch, 7.5*inch, 'Analysis Report') self.canvas.setFont("Helvetica", 20) self.canvas.drawCentredString(4.135*inch, 6.8*inch, 'for data \'' + dataName + '\'') self.canvas.setFont("Helvetica", 15) self.canvas.drawRightString(3.935*inch, 4.4*inch, 'author:') self.canvas.drawRightString(3.935*inch, 3.9*inch, 'date:') self.canvas.drawRightString(3.935*inch, 3.4*inch, 'version:') self.canvas.drawString(4.335*inch, 4.4*inch, author) self.canvas.drawString(4.335*inch, 3.9*inch, str(datetime.now().strftime('%a, %b %d %H:%M'))) self.canvas.drawString(4.335*inch, 3.4*inch, version) self.canvas.showPage() self.page += 1 def body(self): self.header() self.footer() sdataName = self.dataApp.sdataName rdataName = self.dataApp.rdataName imgPath = './spec_data/img/' self.canvas.setFont("Helvetica-Bold", 15) self.canvas.drawString(1.25*inch, 10*inch, 'I. Modulation Factors ') self.canvas.setFont("Helvetica", 12) self.canvas.drawString(1.5*inch, 9.7*inch, 'These factors are derived from the file \''+sdataName+'\'') self.canvas.drawInlineImage(imgPath + sdataName + '_cs0.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.drawInlineImage(imgPath + sdataName + '_cs1.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() self.canvas.drawInlineImage(imgPath + sdataName + '_cs2.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.drawInlineImage(imgPath + sdataName + '_cs3.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() self.canvas.setFont("Helvetica-Bold", 15) self.canvas.drawString(1.25*inch, 10*inch, 'II. Measured Data & FFT ') self.canvas.setFont("Helvetica", 12) self.canvas.drawString(1.5*inch, 9.7*inch, 'The data is derived from the file \''+rdataName+'\', and each fft channel has been filtered.') self.canvas.drawInlineImage(imgPath + rdataName + '_rd.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.drawInlineImage(imgPath + rdataName + '_fft.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() self.canvas.setFont("Helvetica-Bold", 15) self.canvas.drawString(1.25*inch, 10*inch, 'III. Modulation Signals ') self.canvas.setFont("Helvetica", 12) self.canvas.drawString(1.5*inch, 9.7*inch, 'These signals are derived by ifft on the corresponding channel.') self.canvas.drawInlineImage(imgPath + rdataName + '_fa0.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.drawInlineImage(imgPath + rdataName + '_fa1.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() self.canvas.drawInlineImage(imgPath + rdataName + '_fa2.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.drawInlineImage(imgPath + rdataName + '_fa3.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() self.canvas.setFont("Helvetica-Bold", 15) self.canvas.drawString(1.25*inch, 10*inch, 'IV. Stokes Vectors ') self.canvas.setFont("Helvetica", 12) self.canvas.drawString(1.5*inch, 9.7*inch, 'This can be figured out using modulation signals and modulation factors.') self.canvas.drawInlineImage(imgPath + rdataName + '_s0.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.drawInlineImage(imgPath + rdataName + '_s1.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() self.canvas.drawInlineImage(imgPath + rdataName + '_s2.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.drawInlineImage(imgPath + rdataName + '_s3.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() self.canvas.setFont("Helvetica-Bold", 15) self.canvas.drawString(1.25*inch, 10*inch, 'IV. Degree of Polarization ') self.canvas.setFont("Helvetica", 12) self.canvas.drawString(1.5*inch, 9.7*inch, 'This was figured out using four Stokes vectors.') self.canvas.drawInlineImage(imgPath + rdataName + '_dop.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch) self.canvas.showPage() self.page += 1 self.header() self.footer() windows = self.dataApp.windows self.canvas.setFont("Helvetica-Bold", 15) self.canvas.drawString(1.25*inch, 10*inch, 'V. Data Analysis ') self.canvas.setFont("Helvetica", 12) self.canvas.drawString(1.5*inch, 9.7*inch, 'This was automatically generated by program.') self.canvas.drawString(1.5*inch, 9.0*inch, '-The number of the peaks recognized in `FFT` datagram:') self.canvas.drawString(2.0*inch, 8.7*inch, str(len(windows)) + ' peaks') self.canvas.drawString(1.5*inch, 8.4*inch, '-The range of the peaks recognized in `FFT` datagram:') for i in range(0,len(windows)): self.canvas.drawString(2.0*inch, (8.1-i*0.3)*inch, '[' + str(i)+ '] ' +str(windows[i][0])) self.canvas.drawString(3.9*inch, (8.1-i*0.3)*inch, '~ ' + str(windows[i][1])) self.canvas.showPage() self.page += 1 def gen(self): self.cover({ 'dataName' : self.dataApp.rdataName + '`C spec', 'author' : 'ycroft', 'version' : 'v0.1' }) self.body() self.canvas.save()
textobject.setTextOrigin(0.7 * inch, 6 * inch) textobject.setFont('Helvetica-Bold', 49) c.setFillColorRGB(0, 0, 0) textobject.textLines('''S C X 9''') c.drawText(textobject) textobject = c.beginText() textobject.setTextOrigin(3.4 * inch, 6.25 * inch) textobject.setFont('Helvetica', 12.5) c.setFillColorRGB(0, 0, 0) textobject.textLines('''DAS VOLLSTAHL-AUFZUGSEIL THE STEEL CORE ELEVATOR ROPE''') c.drawText(textobject) c.drawImage(logo1, 1, 2.5, width=750, height=425, mask='auto') c.drawInlineImage(rope, 45, 30, width=100, height=40) c.showPage() c.linearGradient(30 * mm, 60 * mm, 30 * mm, 30 * mm, (white, grey)) # for box1 # c.setFillGray(0.8) textobject = c.beginText() textobject.setTextOrigin(0.5 * inch, 11.3 * inch) textobject.setFont('Helvetica-Bold', 12.5) c.setFillColorRGB(0, 0, 0) textobject.textLines('''SCX9 - SCX9 -''') c.drawText(textobject) textobject = c.beginText()
class PDFgenerator: """ Uses opencv to import and parse images. It can find and cut out postits with configured colors """ _outputfile = 'o.pdf' _pageformat = A4 _canvas = None _font = 'Helvetica' _fontsize = 14 _width, _height = A4 _padding = { 'left': 2 * cm, 'right': 1.5 * cm, 'top': 1.5 * cm, 'bottom': 1.5 * cm } _innerWidth = _width - _padding['left'] - _padding['right'] _innerHeight = _height - _padding['top'] - _padding['bottom'] def __init__(self, outputfile=None): """ __init__(outputfile : string) -> void inits class. Sets output File when given as parameter. """ if outputfile is not None: self.setOutput(outputfile) def setOutput(self, path): """ setOutput(path : string) -> void sets output path of generated PDF. Can only be done if canvas hasn't been instaciated yet. If it fails it returns without changing """ if self._canvas is not None: print( 'DEBUG: Pfad kann nach beginn des Erstellens nicht geändert werden' ) return self._outputfile = path def createFile(self): """ createFile() -> void instanciate canvas object """ self._canvas = Canvas(self._outputfile, pagesize=self._pageformat) def saveFile(self): """ saveFile() -> void save PDF file and end editing """ self._canvas.save() self._canvas = None def insertNewPage(self): """ insertNewPage() -> void add page break """ self._canvas.showPage() def insertImage(self, image, x=None, y=None, width=None, height=None, keepAspectRatio=True): """ insertImage(self, image : PIL Object, x : int, y : int, width : int, height : int, keepAspectRatio : bool) -> void insert image with the given params. If no param is set it will use the original PIL object size and/or fit it to the page size. """ im_width, im_height = image.size _width = width _height = height _x = x _y = y _keepAspectRatio = keepAspectRatio if width is None: if im_width >= self._innerWidth: _width = self._innerWidth else: _width = im_width if height is None: if im_height >= self._innerHeight: _height = self._innerHeight else: _height = im_height if x is None: _x = self._padding['left'] if y is None: _y = self._padding['bottom'] try: self._canvas.drawInlineImage(image, x=_x, y=_y, width=_width, height=_height, preserveAspectRatio=_keepAspectRatio, anchor='c') self.insertNewPage() except BaseException as e: print(image) print('failed to process Image', e) def insertText(self, x, y, string, fontsize=_fontsize, fontname=_font): """ insertText(self, x : int, y : int, string : str, fontsize : int, fontname : str) -> void ad text with the given param. If no param is set it will use standard valued (size 12 and Helvetica) """ print('fontsize:', fontsize) print('fontname:', fontname) self._canvas.setFont(fontname, fontsize) self._canvas.drawString(x, y, string) def getOutputFile(self): """ getOutputFile() -> str return the output file path """ return self._outputfile def getPadding(self): """ getPadding() -> int[] return the array which contains the page padding """ return self._padding
def get(self, request, *args, **kwargs): self.object = self.get_object() response = HttpResponse(content_type='application/pdf') response['Content-Disposition'] = 'attachment; filename="{0}-{1}.pdf"'.format(self.object.registru.serie, self.object.numar_inregistrare) pdf = Canvas(response, pagesize = A4) import os from reportlab.lib.styles import getSampleStyleSheet from reportlab.platypus import Paragraph pdfmetrics.registerFont(TTFont("DejaVuSans-Bold", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf")) pdfmetrics.registerFont(TTFont("DejaVuSans", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf")) if self.object.registru.centru_local.antet: antet_path = os.path.join(settings.MEDIA_ROOT, "%s" % self.object.registru.centru_local.antet) pdf.drawInlineImage(antet_path, 2.5 * cm, 10.8 * cm, width=16. * cm, height=2.66 * cm) pdf.drawInlineImage(antet_path, 2.5 * cm, 24.5 * cm, width=16. * cm, height=2.66 * cm) pdf.setStrokeColorRGB(0, 0, 0) pdf.rect(2. * cm, 2. * cm, 17. * cm, 12. * cm) pdf.rect(2. * cm, 15.7 * cm, 17. * cm, 12 * cm) pdf.setStrokeColorRGB(0.5, 0.5, 0.5) pdf.setDash(1, 2) pdf.line(0 * cm, 14.85 * cm, 21. * cm, 14.85 * cm) pdf.setFont("DejaVuSans-Bold", 0.5 * cm, leading=None) pdf.drawCentredString(10.5 * cm, 9.5 * cm, u"Chitanță") pdf.drawCentredString(10.5 * cm, 23.2 * cm, u"Chitanță") text_serie = u"seria {0}, nr. {1} / {2}".format(self.object.registru.serie, self.object.numar_inregistrare, self.object.data_inregistrare.strftime("%d.%m.%Y")) pdf.setFont("DejaVuSans-Bold", 4. * cm, leading=None) pdf.setFillColorRGB(0.95, 0.95, 0.95) pdf.rotate(15) pdf.drawString(4.5 * cm, 2. * cm, u"COPIE") pdf.rotate(-15) pdf.setFillColorRGB(0, 0, 0) pdf.setFont("DejaVuSans", 0.35 * cm, leading=None) pdf.drawCentredString(10.5 * cm, 8.9 * cm, text_serie) pdf.drawCentredString(10.5 * cm, 22.6 * cm, text_serie) reprezinta = self.object.descriere if hasattr(self.object, "chitantacotizatie"): reprezinta = [] for p in self.object.chitantacotizatie.platacotizatietrimestru_set.all().order_by("index"): date_reprezinta = (p.trimestru.__unicode__(), p.suma, u"- parțial" if p.partial else "") reprezinta.append("{0} ({1} RON{2})".format(*date_reprezinta)) reprezinta = ", ".join(reprezinta) reprezinta = u"cotizație membru pentru {0}".format(reprezinta) date_chitanta = (self.object.platitor().__unicode__(), self.object.suma, suma2text(self.object.suma).strip(), reprezinta) text_chitanta = u"Am primit de la <strong>{0}</strong> suma de {1} lei, adică {2}, reprezentând {3}.".format(*date_chitanta) style_sheet = getSampleStyleSheet() style = style_sheet['Normal'] style.alignment = TA_JUSTIFY style.fontName = "DejaVuSans" style.leading = 0.85 * cm paragraph = Paragraph(text_chitanta, style) w, h = paragraph.wrap(15. * cm, 5. * cm) # print w, h paragraph.drawOn(pdf, 3. * cm, 5.5 * cm) paragraph.drawOn(pdf, 3. * cm, 19.2 * cm) pdf.drawString(12.5 * cm, 4.5 * cm, u"Casier,") pdf.drawString(12.5 * cm, 18.2 * cm, u"Casier, ") trezorier = self.object.registru.centru_local.ocupant_functie(u"Trezorier Centru Local") pdf.drawString(12.5 * cm, 3.8 * cm, trezorier.__unicode__()) pdf.drawString(12.5 * cm, 17.5 * cm, trezorier.__unicode__()) pdf.showPage() pdf.save() return response
img2 = cv2.imread(FILENAME + str(0) + "." + EXT) img = cv2.imread(FILENAME + str(0) + "." + EXT) img = np.vstack((img, img, img, img, img, img)) cv2.imwrite("lol.png", img) detector = cv2.QRCodeDetector() #data, bbox, straight_qrcode = detector.detectAndDecode(img) #data = decode(img) PatchSize = 5 * cm spacing = 1 * cm i = 2 A = 3 hspace = (A4[0] - A * PatchSize) / (A + 1) B = 5 vspace = (A4[1] - B * PatchSize) / (B + 1) #img2 = Image.fromarray(images[2], 'RGB') #canvas.drawInlineImage("genCode0.png", spacing, A4[1]-spacing-PatchSize, PatchSize, PatchSize) for i, img in enumerate(images): j = math.floor((i / A) % (B)) + 1 k = i % A p = math.floor(i / A / B) if i != 0 and i % (A * B) == 0: canvas.showPage() print("Page = " + str(p) + ", j = " + str(j) + ", K = " + str(k)) canvas.drawInlineImage(img, hspace + (hspace + PatchSize) * k, A4[1] - (vspace + PatchSize) * j, PatchSize, PatchSize) canvas.save()
def generatePDF(time, audio, maxAmp, maxAmpTime, minAmp, minAmpTime, totalTime, datas, speech, audioName, audioDate, audioGraf, username, audioId): data = [] #datas = datas['words'] date = datetime.now() calenderDate = str(date).split(" ") separetedDate = calenderDate[0].split("-") formattedDate = separetedDate[2] + "/" + separetedDate[ 1] + "/" + separetedDate[0] try: relatorio = BytesIO() pdf = Canvas(relatorio, pagesize=LETTER) pdf.setFont("Helvetica-Bold", 20) pdf.drawString(190, 740, 'Relatório da Análise de Audio') pdf.drawInlineImage("apnealogo.png", -20, 645, 200, 180) pdf.setFont("Helvetica", 10) pdf.drawString(520, 750, 'Gerado em:') pdf.drawString(520, 738, formattedDate) pdf.line(20, 690, 585, 690) pdf.setFont("Helvetica-Bold", 16) pdf.drawString(230, 670, 'Dados do Audio') pdf.setFont("Helvetica", 14) pdf.drawString(22, 650, f'Nome do Audio: {audioName}') pdf.drawString(22, 630, f'Data de envio: {audioDate}') pdf.drawString( 22, 610, f'Tempo Total do audio: {format(totalTime,".2f")} segundos') pdf.drawString(22, 590, f'Amplitude máxima: {str(format(maxAmp,".2f"))}') pdf.drawString( 22, 570, f'Tempo da amplitude máxima: {str(format(maxAmpTime, ".2f"))} segundos' ) pdf.drawString(22, 550, f'Amplitude mínima: {str(format(minAmp,".2f"))}') pdf.drawString( 22, 530, f'Tempo da amplitude mínima: {str(format(minAmpTime,".2f"))} segundos' ) pdf.line(20, 510, 585, 510) pdf.setFont("Helvetica-Bold", 16) pdf.drawString(230, 485, 'Fala Detectada') pdf.setFont("Helvetica", 14) speechLines = wrap(speech, 88) speechy = 480 for line in speechLines: speechy -= 20 pdf.drawString(22, speechy, line) for json in datas: data.append((json['word'], json['startTime'], json['endTime'])) print(json['word'], json['startTime'], json['endTime']) data.insert(0, ("Palavra", "Tempo de Início\n(segundos)", "Tempo de fim\n(segundos)")) table = generateTable(data) newPdfs = [] generateNewPDF(table, 0, [], (speechy - 50), (speechy - 20), pdf, newPdfs, relatorio) pdf_writer = PdfFileWriter() newPdfs.append(audioGraf) for path in newPdfs: pdf_reader = PdfFileReader(path) for page in range(pdf_reader.getNumPages()): pdf_writer.addPage(pdf_reader.getPage(page)) relatorioFinal = BytesIO() with relatorioFinal as pdf: pdf_writer.write(pdf) print("PDF Gerado com sucesso") #Generate file key for pdf fileKey = generateFileKey(username, audioId, ".pdf", audioName) #Call method to save audio file to S3 saveFileS3("apneasleepbucket", fileKey, pdf.getvalue()) return fileKey except Exception as e: print(e) return 'Erro ao gerar PDF'