Eliminare scritta da ogni pagina di un PDF

Postate qui per tutte le discussioni legate a Linux in generale.

Moderatore: Staff

Regole del forum
1) Citare sempre la versione di Slackware usata, la versione del Kernel e magari anche la versione della libreria coinvolta. Questi dati aiutano le persone che possono rispondere.
2) Per evitare confusione prego inserire in questo forum solo topic che riguardano appunto Gnu/Linux in genere, se l'argomento è specifico alla Slackware usate uno dei forum Slackware o Slackware64.
3) Leggere attentamente le risposte ricevute
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Eliminare scritta da ogni pagina di un PDF

Messaggio da joe »

Ho un PDF di 300 pagine circa.
È un libro disponibile elettronicamente, liberamente scaricabile, ma presenta su ciascuna pagina la scritta: "COPIA DI CONSULTAZIONE". La scritta copre tutta la pagina ed è disposta in diagonale.

La funzione di quella scritta è chiaramente la seguente: "se vuoi il libro senza la scritta compralo, altrimenti ti accontenti di questa copia gratuita imbruttita e semi coperta dalla scritta in oggetto". Ora, personalmente e a scanso di equivoci possiedo già il libro sopracitato in cartaceo, tra l'altro fornitomi a gratis da un associazione d'assistenza di cui faccio parte, ma mi farebbe molto comodo averlo in formato PDF, banalmente perchè non pesa e lo avrei sempre a portata di monitor, pronto per essere consultato anche quando non ho il libro cartaceo sottomano.

Ora, l'obiettivo sarebbe: eliminare da ciascuna pagina del PDF la scritta diagonale "COPIA DI CONSULTAZIONE" che rompe le scatole.

La soluzione banale: apro il PDF con libreoffice, vado alla prima pagina, la scritta da eliminare risulta essere un riquadro testuale e non un'immagine, lo seleziono click destro e scelgo taglia o schiaccio "canc"... Insomma la scritta scompare. E penso (non ho provato a dire il vero) che se salvo in quel modo il PDF la pagina modificata dovrebbe apparire pulita, senza la scritta che ho eliminato.
Ora, l'operazione dovrebbe essere poi ripetuta per tutte le 300 pagine del libro. Capite bene lo sbattimento.

Quindi all'obiettivo va aggiunta la possibilità di eseguire l'operazione in modo automatico, in un colpo solo. Da come ho visto in rete la cosa è anche tecnicamente possibile.

http://superuser.com/questions/448519/h ... sing-pdftk

In pratica:
1- apro il sorgente del PDF
2- individuo il sorgente della scritta da eliminare
3- lo elimino da tutto il documento con sed.
4- riaggiusto il PDF con pdftk

Il problema è come fare ad individuare la parte di sorgente relativa alla nostra scritta "COPIA DI CONSULTAZIONE".
Servirebbe per esempio il corrispondente della funzione che si ha nel browser "ispeziona elemento"... in modo da selezionare nel PDF la scritta incriminata e vederne il sorgente corrispondente in modo da copiarlo ed incollarlo nel pattern di sed.

Avete qualche idea di come poter risolvere la cosa, anche al di là delle soluzioni che ho buttato lì io?
Grazie come al solito! :)

Avatar utente
murdock
Linux 2.x
Linux 2.x
Messaggi: 477
Iscritto il: ven 25 mag 2007, 12:58
Slackware: 64 14.1
Kernel: 3.18.3
Desktop: KDE 4.14.3
Contatta:

Re: Eliminare scritta da ogni pagina di un PDF

Messaggio da murdock »

Se "mastichi" un po' il Perl potresti provare con CAM::PDF http://search.cpan.org/dist/CAM-PDF
In realtà in Perl ci sono un sacco di moduli per fare dei PDF più o meno ciò che si vuole http://search.cpan.org/search?query=pdf&mode=all ;)

Saluti,
MuRdOcK

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: Eliminare scritta da ogni pagina di un PDF

Messaggio da joe »

Purtroppo il perl mi manca...
Devo dire che non mi resta proprio intuitivo come dovrei usare quel modulo.
Vedo questo ad esempio:
http://search.cpan.org/dist/CAM-PDF/bin ... estring.pl

Codice: Seleziona tutto

changepagestring.pl [options] infile.pdf search-regex replace-str [outfile.pdf]
Ma quindi basterebbe quel comando lì?

Del tipo:

Codice: Seleziona tutto

changepagestring.pl infile.pdf "COPIA DI CONSULTAZIONE" "" [outfile.pdf]
Mi pare troppo semplice...
Cosa ne dici?

Avatar utente
murdock
Linux 2.x
Linux 2.x
Messaggi: 477
Iscritto il: ven 25 mag 2007, 12:58
Slackware: 64 14.1
Kernel: 3.18.3
Desktop: KDE 4.14.3
Contatta:

Re: Eliminare scritta da ogni pagina di un PDF

Messaggio da murdock »

Dovrebbe funzionare,
considera però che in quegli script pl viene usato il modulo perl CAM::PDF ,se non lo installi nelle perl libs non verrà trovato.
Puoi installare moduli Perl utilizzando cpan http://www.cpan.org/modules/INSTALL.html, in alternativa trovi tutte le istruzioni per l'installazione manuale all'interno del file README nel pacchetto tar gz del modulo che ti interessa (scaricato preventivamente da cpan.org), nel tuo caso CAM::PDF ed eventuali dipendenze.
Se perl non trova un modulo ne segnalerà la mancanza nel @inc, per esempio:

Codice: Seleziona tutto

Can't locate CAM/PDF.pm in @INC (you may need to install the CAM::PDF module)
Saluti,
MuRdOcK

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: Eliminare scritta da ogni pagina di un PDF

Messaggio da joe »

È bastato lanciare:

Codice: Seleziona tutto

cpan CAM::PDF
Adesso changepagestring.pl è disponibile.
Ma non fà quanto richiesto.

La sostituzione impostata non ha prodotto alcun risultato sul pdf in output che contiene ancora la scritta da eliminare.
Ho provato anche a vedere se intercettava altre parti del pdf, usando altri pattern ad esempio

Codice: Seleziona tutto

changepagestring.pl -v uncompressed.pdf "Capitolo" "CAPITOLO" outfile.pdf
Ma nell'outfile.pdf vi è sempre scritto Capitolo (in questo caso la parola Capitolo è ricorrente nell'indice e nell'intestazione delle pagine).

Ho tentato anche con un altro PDF, che pare meno complicato... Ma anche lì niente da fare, ho preso una parola presente nel documento e l'ho usata come stringa di ricerca data in pasto a chngepagestring. Però anche qui non ha funzionato..

Se avete qualche idea...

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: Eliminare scritta da ogni pagina di un PDF

Messaggio da joe »

Forse ho capito perchè non funziona... Ma non saprei come risolvere, almeno per il momento:
Nel PDF potrebbe essere che quella che io vedo come una "frase" in diagonale e cioè "COPIA DI CONSULTAZIONE", sia in realtà un'insieme di "lettere singole" disposte in modo "non consecutivo" all'interno del sorgente del pdf..

Ho usato "pdftohtml" per convertire il PDF in HTML appunto. E ho visto che in effetti ci sono delle righe contenenti lettere maiuscole che sembrano messe lì a caso... Ma chissà che magari quelle lettere rappresentino anche alcune lettere facenti parte della scritta che voglio eliminare.

Ho fatto una prova cercando di eliminare ad esempio la lettera "C":

Codice: Seleziona tutto

changepagestring.pl -v uncompressed.pdf "C" "" outfile.pdf
E in questo modo la "C" sparisce dalla scritta diagonale "COPIA DI CONSULTAZIONE" che aprendo il pdf si vede trasformata in "OPIA DI ONSULTAZIONE".
Il problema è che in questo modo si fanno fuori tutte le "C" presenti nel documento...
Ho anche provato per vedere cosa succede, a prendere l'output dell'eliminazione della "C" e darlo in input allo script ordinandogli di togliere la "O" cioè la lettera successiva. Funziona ma con le stesse limitazioni spiegate sopra. Poi sono andato avanti a togliere la "P"... per farla breve ecco i passaggi che ho fatto:

Codice: Seleziona tutto

$ changepagestring.pl -v uncompressed.pdf "C" "" C_outfile.pdf
changepagestring.pl -v C_outfile.pdf "O" "" CO_outfile.pdf
changepagestring.pl -v CO_outfile.pdf "P" "" COP_outfile.pdf
changepagestring.pl -v COP_outfile.pdf "I" "" COPI_outfile.pdf
changepagestring.pl -v COPI_outfile.pdf "A" "" COPIA_outfile.pdf
changepagestring.pl -v COPIA_outfile.pdf "D" "" COPIAD_outfile.pdf
changepagestring.pl -v COPIAD_outfile.pdf "N" "" COPIADN_outfile.pdf
ecc ecc...
Però ad un certo punto accade che davvero troppe lettere vengono cancellate anche la dove servono veramente e non solo dalla scritta diagonale che si vuole eliminare...

Servirebbe un discriminante che eliminasse ad esempio tutte le "C" di dimensione maggiore di un certo tot... e lasciasse stare le altre...
In questo modo "solo" le "C" della scritta da buttare scomparirebbero, perchè la nostra scritta diagonale preposta per coprire la pagina e rendere la lettura molto scomoda è scritta con un carattere cubitale... molto maggiore di ogni altra dimensione di font usata nel resto del documento.

Allora a voi la domanda... (E a me la ricerca in tal senso):
Come potrebbe essere utilizzato il programmino in perl di cui sopra o qualche altro simile per "greppare" solo i caratteri di una certa dimensione?

Riformulando la stessa domanda: in un file PDF (nel sorgente intendo) come viene definita la dimensione del font di un carattere?
Intendo, perchè la "C" che mi interessa eliminare è grandissima mentre altre "C" presenti nel documento appaiono ben inferiori? Ci dovrà pur essere un discriminante nel testo del sorgente che dice al viewer di rendere a schermo una certa lettera con una particolare dimensione, non vi pare?
Ne sapete qualcosa in più di me che come potete vedere vado completamente a naso?

Avatar utente
murdock
Linux 2.x
Linux 2.x
Messaggi: 477
Iscritto il: ven 25 mag 2007, 12:58
Slackware: 64 14.1
Kernel: 3.18.3
Desktop: KDE 4.14.3
Contatta:

Re: Eliminare scritta da ogni pagina di un PDF

Messaggio da murdock »

Vado a "naso" anche io, forse utilizzando come pattern di ricerca una cosa tipo

Codice: Seleziona tutto

C\s+O\s+P\s+I\s+A\s+D\s+I\s+C\s+O\s+N\s+S\s+U\s+L\s+T\s+A\s+Z\s+I\s+O\s+N\s+E
:?:

Saluti,
MuRdOcK

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: Eliminare scritta da ogni pagina di un PDF

Messaggio da joe »

Non funge... eh sarebbe troppo semplice così ;)

In realtà mi sa che il sorgente di un PDF sia qualcosa che necessita un po' più di approfondimento per capire come intervenire sull'editing.
Qua spiegano qualcosa in modo abbastanza semplice:
https://blog.idrsolutions.com/2010/10/m ... -world-pdf

In particolare sul "Size" del font utilizzato per un certo elemento testuale.
Altre info a partire da qui:
http://stackoverflow.com/questions/8858 ... a-pdf-file
Vedo cosa ne esce...

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: Eliminare scritta da ogni pagina di un PDF

Messaggio da joe »

Grande botta di deretano! :D

Leggendo quanto spiega nel primo link ecco che ho osservato, aprendo il pdf con vim che ci sono delle ricorrenti parti di sorgente con un "size" più grosso del resto (36).
Che nella fattispecie sono tutti fatti così:

Codice: Seleziona tutto

10 0 0 10 0 0 cm BT
/R16 36 Tf
0.707107 0.707107 -0.707107 0.707107 83.5449 163.052 Tm
[(C)0.167838(O)-0.167838(PI)-0.167838(A )0.19661(D)0.167838(I)-0.167838( )-0.00695329(C)0.167838(O)-0.167838(N)0.168797(SU)0.168797(L)0.152493(T)-0.160165(AZ)-0.159686(I)-0.167838(O)-0.167838(N)0.167838(E )-0.168797]TJ
-35.9912 -43.1998 Td
[(C)0.167838(O)-0.167838(PYR)0.167838(I)-0.167838(G)-0.168797(H)0.168797(T)-0.160165( )0.191815(AN)0.168797(PAS )-0.141943(C)0.167838(O)-0.167838(MI)-0.168317(T)-0.159206(AT)-0.159206(O)-0.168797( )-0.166879]TJ
-5.02792 -43.2001 Td
[(R)0.167838(EG)-0.168317(I)-0.167838(O)-0.167838(N)0.167838(AL)0.152733(E )0.0326085(EMI)-0.167838(L)0.152493(I)-0.167838(A )0.187019(- )0.00191815(R)0.167838(O)-0.167358(MAG)-0.166879(N)0.166879(A)]TJ
ET
Nel link spiegano che "BT" sta per begin text. ET end text... quindi quello che ci sta in mezzo è testo.
"/R16 36 Tf" dovrebbe descrivere il font usato e la sua dimensione, in questo caso la scritta coprente ha un tipo di carattere /R16 (non chiedetemi cosa sia) una grandezza di 36 (anche qui no so se sono punti per pollice o altro...) e Tf è l'istruzione che usa questi dati e imposta così la scritta... Td dice dove posizionarla, Tj, che in questo caso è TJ tutto maiuscolo... teoricamente dovrebbe definire il contenuto del testo ovvero la nostra frase da buttare. In realtà come si vede oltre le lettere della frase (ciascuna messa tra le parentesi tonde) vi sono altri descrittori numerici "0.qualcosa".
Tra le parentesi (mi accorgo solo ora che si legge proprio la scritta che voglio eliminare... lascio alla vostra abilità stanarla. ;)

Bene ora veniamo a quello che mi interessava (siamo in discesa finalmente...).
Devo cancellare dal sorgente del PDF tutte le ricorrenze delle righe riportate lì sopra... dalla parola BT al successivo ET compresi.
Ho provato a farlo manualmente aprendo il PDF con Vim e funziona alla grande: eliminando quella pappa lì, la scritta coprente svanisce rendendo la lettura ovviamente più comoda...

Se avete qualche idea...

PS.
Aprendo il PDF con vim e salvando ":wq" il file viene convertito da un formato simil binario a qualcosa di digeribile anche da altri programmi testuali come less e imamgino anche sed grep e compagnia.

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: Eliminare scritta da ogni pagina di un PDF

Messaggio da joe »

accidenti no... grep non funge..

Codice: Seleziona tutto

grep '\/R16 36 Tf' uncompressed.pdf
Il file binario uncompressed.pdf corrisponde

Avatar utente
murdock
Linux 2.x
Linux 2.x
Messaggi: 477
Iscritto il: ven 25 mag 2007, 12:58
Slackware: 64 14.1
Kernel: 3.18.3
Desktop: KDE 4.14.3
Contatta:

Re: Eliminare scritta da ogni pagina di un PDF

Messaggio da murdock »

Ci riprovo

Codice: Seleziona tutto

BT\n.+\n.+\n\[\(C.+O.+PI.+A.+D.+I.+C.+O.+N.+SU.+L.+T.+AZ.+I.+O.+N.+E.+\n.+Td\n.+\n.+\n.+\nET
:)

Saluti,
MuRdOcK

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: Eliminare scritta da ogni pagina di un PDF

Messaggio da joe »

Codice: Seleziona tutto

changepagestring.pl -v uncompressed.pdf "BT\n.+\n.+\n\[\(C.+O.+PI.+A.+D.+I.+C.+O.+N.+SU.+L.+T.+AZ.+I.+O.+N.+E.+\n.+Td\n.+\n.+\n.+\nET" "" outfile.pdf
Con questo comando se ne và completamente tutto il testo dell'intero documento... "no buono.."

Però mi chiedevo una cosa... perchè vim riesce ad aprire il PDF e a visualizzarne il sorgente come se fosse un file di testo, mentre grep ad esempio fallisce trattando il file come un binario?
Chiaramente poi a me interessa l'editing con qualcosa tipo sed o awk.
In pratica devo dirgli semplicemente: trova la riga del che contiene "/R16 36 Tf" e cancella tutte le righe dalla precedente (quella contenente "BT" èer capirci ) a quella che contiene la prima ricorrenza di "ET".
Però se sed e awk non sono in grado di trattare il binario come un file di testo questo non funzionerà immagino...
Allora intanto cercherò di tradurre la direttiva sopra nel corrispondente comando sed o awk... e poi provo e vi faccio sapere. Se avete qualche dritta alternativa o comunque qualche commento, sarà sicuramente utilissimo per capirci di più.

Grazie! :)

Avatar utente
joe
Iper Master
Iper Master
Messaggi: 3789
Iscritto il: ven 27 apr 2007, 11:21
Slackware: 15.0
Kernel: 5.15.38
Desktop: dwm

Re: Eliminare scritta da ogni pagina di un PDF

Messaggio da joe »

Confermo che sed funzionicchia... Ho provato al volo questo comando, che però non cancella la riga precedente al primo pattern...

Codice: Seleziona tutto

sed '/\/R16 36 Tf/,/ET/d' uncompressed.pdf > outfile.pdf
Con questa non viene cancellata appunto la riga:

Codice: Seleziona tutto

10 0 0 10 0 0 cm BT
Il PDF in uscita l'ho aperto ad esempio con XPDF. Si apre ma a shell dà un errore:

Codice: Seleziona tutto

$ xpdf outfile.pdf 
Syntax Error: Couldn't read xref table
Syntax Warning: PDF file is damaged - attempting to reconstruct xref table...
Penso ciò sia dovuto al begin text rimasto orfano di tutto ciò che seguiva.

EDIT:
Ho provato anche a cancellare la riga precedente al pattern... l'errore persiste però.
Come ho fatto:

Codice: Seleziona tutto

$ vim -e uncompressed.pdf <<@@@
g/\/R16 36 Tf/?10 0 0 10 0 0 cm BT?,/ET/d
wq
@@@
questa no la conoscevo... buono a sapersi: cancella un pezzo di file tra due righe definite se tra le due vi è una terza riga corrispondente al nostro pattern. Altre soluzioni con sed e awk mi sono sembrate più complicate...

Ad ogni modo in questo modo il file di partenza viene modificato direttamente ne ho fatto il backup prima, ma mi piaceva di più risputare l'output in un nuovo file, va bè non importa..
Ora però persiste il problema dell'errore di cui sopra.
Per risolverlo ho aggirato il problema:

Codice: Seleziona tutto

$ pdftops uncompressed.pdf outfile.ps
$ ps2pdf outfile.ps outfile.pdf
E questo passaggio produce un PDF in uscita, sano e senza l'odiosa scritta diagonale che copriva il testo.
L'output è anche molto più leggero dell'input di partenza:

Codice: Seleziona tutto

$ ls -lh outfile.pdf uncompressed.pdf
-rw-r--r-- 1 joe dialout 2,5M dic  4 00:50 outfile.pdf
-rw-r--r-- 1 joe dialout 6,6M dic  4 00:46 uncompressed.pdf
Forse perchè si perde qualcosa in qualità delle immagini?
Non so, nel mio caso mi basta e avanza...
Mission complete! direi... :)

Chissà che no torni utile anche ad altri!
Alla prossima e grazie per le risposte. torno a dire, ogni commento sarà utile in ogni caso, come sempre! :D

Rispondi