PHP: Convertire e Proteggere un PDF multipagina

Ho avuto necessità di crearmi uno strumento, fruibile online, che mi consenta di caricare un PDF – generato da un programma di Office, quindi, con testo e immagini selezionabili e copiabile – in uno che invece non consenta la copia, anzi, deve trattarsi di pagine costituite da immagini (praticamente il testo e le immagini vengono convertite in immagini, una sorta di screenshot delle varie pagine) che, via via, risultano sempre più offuscate fino a risultare illeggibili.

Chiaramente le necessità di offuscamento varieranno a seconda delle proprie necessità ma, grosso modo, do qui qualche consiglio su come operare la cosa in PHP.

La prima cosa da fare è creare un oggetto “Imagick” del manuale che vogliamo convertire:

$imagick = new Imagick();

Dato che un PDF convertito da “testo in immagine” può aumentare notevolmente le dimensioni, può essere opportuno variarne la risoluzione; io ho optato per una cosa di questo tipo:

$imagick->setResolution(50, 50);

ma, chiaramente, variando i valori – o non mettendo proprio la riga – si possono ottenere risultati diversi.

Fatto questo bisogna caricare il file PDF, così:

$imagick->readImage('file.pdf');

Il file così caricato va a creare un array nell’oggetto “imagick” che può essere elaborato in questo modo:

foreach ($imagick as $key => $image) {
 $image->adaptiveBlurImage($key / 5, $key / 5);

dove “$image” rappresenta la singola pagina e “$key” il numero di pagina.

Tramite il metodo “adaptiveBlurImage” si ottiene una sfocatura delle pagine; nel mio caso, dato che lego i valori di sfocatura al numero della pagina in elaborazione, ottengo un effetto che va ad aumentare progressivamente.

Dato che, come dicevo sopra, la dimensione del PDF potrebbe aumentare considerevolmente (un file da 1Mb può tranquillamente diventare 10Mb, cioè 10 volte tanto o peggio), ho optato per un troncamento del PDF dopo una certa pagina, in questo modo:

 if ($key >= 25) {
  $image->removeImage();
 }
}

Nel mio caso specifico, non contento, ho anche voluto aggiungere un testo (dopo un certo numero di pagina) in sovrapposizione e l’ho ottenuto con un codice come il seguente:

$draw = new ImagickDraw();
$draw->setFillColor('#000000');
$draw->setFontSize(16);
$draw->setTextUnderColor('#ff000088');

nel quale ho preparato l’oggetto da sovrapporre alle varie pagine (quindi prima del ciclo “foreach” di cui sopra) e ho applicato il medesimo con:

$image->annotateImage($draw, 20, 170, 0, $messaggio);

dove “$messaggio” è chiaramente una variabile che possiamo impostare in precedenza a piacimento, con tanto di “ritorno a capo” costituito dalla sequenza di escape “\n”.

Infine, per salvare il risultato, ho usato:

$imagick->writeImages('file_preview.pdf', true);

che serve per salvare tutte le pagine PDF e non solo l’ultima.

Infine, per farmi spedire il risultato, ho usato:

header("Content-type: Application/pdf");
header("Content-Description: PDF Protetto");
header("Content-Length: ".filesize("file_preview.pdf"));
header('Content-Disposition: attachment; filename="file_preview.pdf"');
readfile("file_preview.pdf");

Quello che si ottiene è un PDF Protetto – il cui contenuto non può essere copiato e nemmeno riconosciuto da un OCR – che si può spedire come “anteprima” di quello originale.

Autore: BuDuS

Disegnatore Meccanico, con la passione per l'Informatica. Come hobby, produco piccoli software di (in)utilità.