Di recente mi è capitato di dover aggiungere ad un documento PDF esistente, un’immagine cliccabile che rimandasse ad un sito web. Le motivazioni possono essere diverse, la prima che mi viene in mente è, ad esempio, aggiungere un collegamento ipertestuale al sito web dell’autore.
La soluzione proposta utilizza Python e in particolare due librerie PyPDF2 e reportlab.
La prima è utilizzata per aggiungere nella pagina un’area sensibile al clic, la seconda per aggiungere un’immagine. L’idea è quella di posizionare l’immagine e l’area sensibile nella stessa posizione in modo da far sembrare l’immagine cliccabile.
Riporto come di consueto il frammento di codice.
Dopo aver importato le librerie necessarie, definiamo la funzione add_image(filename, x_max, y_max) che prende in input il nome del file da modificare e le coordinate del suo angolo in alto a destra.
import PyPDF2 from PyPDF2 import PdfWriter, PdfReader from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import letter, landscape import io #file da modificare docs = ["1.pdf", "2.pdf", "3.pdf"] #nome dell'immagine image_file = 'button.png' #dimensioni dell'immagine image_width = 72 image_height = 85 def add_image(filename, x_max, y_max): in_pdf_file = filename out_pdf_file = "MODIFICATI/"+filename packet = io.BytesIO() size = [x_max, y_max] can = canvas.Canvas(packet, pagesize=size) x_start = x_max - image_width y_start = y_max - image_height can.drawImage(image_file , x_start, y_start, width=image_width , preserveAspectRatio=True, mask='auto', showBoundary=False) can.showPage() can.save() packet.seek(0) new_pdf = PdfReader(packet) existing_pdf = PdfReader(open(in_pdf_file, "rb")) output = PdfWriter() for i in range(len(existing_pdf.pages)): page = existing_pdf.pages[i] page.merge_page(new_pdf.pages[i]) output.add_page(page) outputStream = open(out_pdf_file, "wb") output.write(outputStream) outputStream.close() for filename in files: with open(filename, 'rb') as file: pdf_reader = PyPDF2.PdfReader(file) pdf_writer = PyPDF2.PdfWriter() if len(pdf_reader.pages) > 0: box = pdf_reader.pages[0].mediabox # coordinate del bordo in alto a destra della pagina x_max = round(box[2]) y_max = round(box[3]) for page_num in range( len(pdf_reader.pages) ): page = pdf_reader.pages[page_num] pdf_writer.add_page(page) annotation = PyPDF2.generic.AnnotationBuilder.link( rect=(x_max-image_widht, y_max-image_height,x_max,y_max), url="https://www.mydomain.com") pdf_writer.add_annotation(page_number=0, annotation=annotation) with open("MODIFICATI/"+filename, 'wb') as file: pdf_writer.write(file) add_image(filename, x_max, y_max) print("OK: "+filename)
La funzione crea un Canvas delle dimensioni della pagina PDF e ci disegna l’immagine data nel bordo in alto a destra. Qiindi crea un nuovo documento PDF a partire dal Canvas e lo unisce, pagina per pagina, al contenuto del file originario, quindi salva il nuovo file ottenuto.
Il blocco di codice principale, invece, cicla tra tutti i file contenuti nell’array files e, per ciascuno di essi, apre il file, ne ricava le dimensioni della prima pagina (pdf_reader.pages[0].mediabox).
Quindi inserisce, attraverso un oggetto pdf_writer, ciascuna pagine del file in origine, su un nuovo documento PDF (pdf_writer.add_page(page)).
Nella prima pagina del nuovo documento, inserisce qundi un link, attraverso la funzione PyPDF2.generic.AnnotationBuilder.link definendo le coordinate del rettangolo sensibile al clic.
Quindi il nuovo file viene salvato per poi essere riaperto dalla funzione che aggiunge l’immagine alla prima pagina.