Questa recensione è stata approvata da specialisti, quindi garantiamo l'accuratezza della nostra recensione.
Soluzione:
- Mettere tutti i file .pdf in una cartella.
- Nessun file .txt nella cartella.
- Nel terminale cambiare la directory in quella cartella con
cd
- Creare un'altra cartella per i file non scansionati. Esempio:
mkdir ./x
for file in *.pdf; do
if [ $(pdftotext "$file")"x" == "x" ] ; then mv "$file" ./x; fi
rm *.txt
done
Tutti i file pdf scansionati rimarranno nella cartella e gli altri file verranno spostati in un'altra cartella.
Shellscript
-
Se un
pdf
contiene un'immagine (inserita in un documento accanto al testo o come pagine intere, 'pdf scansionato'), il file spesso (forse sempre) contiene la stringa/Image/
. -
Allo stesso modo è possibile cercare la stringa
/Text
per sapere se un file pdf contiene testo (non scansionato).
Ho creato lo shellscript pdf-text-or-image
e potrebbe funzionare nella maggior parte dei casi con i vostri file. Lo shellscript cerca le stringhe di testo /Image/
e /Text
nel file pdf
file.
#!/bin/bash
echo "shellscript $0"
ls --color --group-directories-first
read -p "Is it OK to use this shellscript in this directory? (y/N) " ans
if [ "$ans" != "y" ]
then
exit
fi
mkdir -p scanned
mkdir -p text
mkdir -p "s-and-t"
for file in *.pdf
do
grep -aq '/Image/' "$file"
if [ $? -eq 0 ]
then
image=true
else
image=false
fi
grep -aq '/Text' "$file"
if [ $? -eq 0 ]
then
text=true
else
text=false
fi
if $image && $text
then
mv "$file" "s-and-t"
elif $image
then
mv "$file" "scanned"
elif $text
then
mv "$file" "text"
else
echo "$file undecided"
fi
done
Rendere eseguibile lo shellscript,
chmod ugo+x pdf-text-or-image
Cambiare la directory in cui si trovano i file pdf
ed eseguire lo shellscript.
I file identificati vengono spostati nelle seguenti sottodirectory
scanned
text
s-and-t
(per i documenti con entrambi i file [scanned?] immagini e contenuto testuale)
Gli oggetti file non identificati, 'UFO', rimangono nella directory corrente.
Test
Ho testato lo shellscript con due dei vostri file, AR-G1002.pdf
e AR-G1003.pdf
e con alcuni propri file pdf
(che ho creato utilizzando Libre Office Impress).
$ ./pdf-text-or-image
shellscript ./pdf-text-or-image
s-and-t mkUSB-quick-start-manual-11.pdf mkUSB-quick-start-manual-nox-11.pdf
scanned mkUSB-quick-start-manual-12-0.pdf mkUSB-quick-start-manual-nox.pdf
text mkUSB-quick-start-manual-12.pdf mkUSB-quick-start-manual.pdf
AR-G1002.pdf mkUSB-quick-start-manual-74.pdf OBI-quick-start-manual.pdf
AR-G1003.pdf mkUSB-quick-start-manual-75.pdf oem.pdf
DescriptionoftheOneButtonInstaller.pdf mkUSB-quick-start-manual-8.pdf pdf-text-or-image
GrowIt.pdf mkUSB-quick-start-manual-9.pdf pdf-text-or-image0
list-files.pdf mkUSB-quick-start-manual-bas.pdf README.pdf
Is it OK to use this shellscript in this directory? (y/N) y
$ ls -1 *
pdf-text-or-image
pdf-text-or-image0
s-and-t:
DescriptionoftheOneButtonInstaller.pdf
GrowIt.pdf
mkUSB-quick-start-manual-11.pdf
mkUSB-quick-start-manual-12-0.pdf
mkUSB-quick-start-manual-12.pdf
mkUSB-quick-start-manual-8.pdf
mkUSB-quick-start-manual-9.pdf
mkUSB-quick-start-manual.pdf
OBI-quick-start-manual.pdf
README.pdf
scanned:
AR-G1002.pdf
text:
AR-G1003.pdf
list-files.pdf
mkUSB-quick-start-manual-74.pdf
mkUSB-quick-start-manual-75.pdf
mkUSB-quick-start-manual-bas.pdf
mkUSB-quick-start-manual-nox-11.pdf
mkUSB-quick-start-manual-nox.pdf
oem.pdf
Speriamo che
- non ci siano UFO nel vostro insieme di file
- l'ordinamento sia corretto per quanto riguarda il testo rispetto alle immagini scannerizzate
Se si tratta di rilevare effettivamente se il PDF è stato creato dalla scansione piuttosto che il pdf ha immagini invece di testo allora potrebbe essere necessario scavare nei metadati del file, non solo nel contenuto.
In generale, per i file che ho trovato sul mio computer e per i vostri file di prova, è vero quanto segue:
- I file scansionati hanno meno di 1000caratteri/pagina rispetto a quelli non scansionati che hanno sempre più di 1000caratteri/pagina.
- Diversi file scansionati indipendenti riportavano "Canon" come creatore di PDF, probabilmente riferendosi al software dello scanner Canon.
- È probabile che i PDF con "Microsoft Word" come creatore non siano stati scansionati, in quanto si tratta di esportazioni di Word. Ma qualcuno potrebbe scansionare in Word e poi esportare in PDF: alcune persone hanno un flusso di lavoro molto strano.
Al momento sto usando Windows, quindi ho usato node.js
per il seguente esempio:
const fs = require("mz/fs");
const pdf_parse = require("pdf-parse");
const path = require("path");
const SHOW_SCANNED_ONES = process.argv.indexOf("scanned") != -1;
const DEBUG = process.argv.indexOf("debug") != -1;
const STRICT = process.argv.indexOf("strict") != -1;
const debug = DEBUG ? console.error : () => { };
(async () => {
const pdfs = (await fs.readdir(".")).filter((fname) => { return fname.endsWith(".pdf") });
for (let i = 0, l = pdfs.length; i < l; ++i) {
const pdffilename = pdfs[i];
try {
debug("nnFILE: ", pdffilename);
const buffer = await fs.readFile(pdffilename);
const data = await pdf_parse(buffer);
if (!data.info)
data.indo = {};
if (!data.metadata) {
data.metadata = {
_metadata: {}
};
}
// PDF info
debug(data.info);
// PDF metadata
debug(data.metadata);
// text length
const textLen = data.text ? data.text.length : 0;
const textPerPage = textLen / (data.numpages);
debug("Text length: ", textLen);
debug("Chars per page: ", textLen / data.numpages);
// PDF.js version
// check https://mozilla.github.io/pdf.js/getting_started/
debug(data.version);
if (evalScanned(data, textLen, textPerPage) == SHOW_SCANNED_ONES) {
console.log(path.resolve(".", pdffilename));
}
}
catch (e) {
if (strict && !debug) {
console.error("Failed to evaluate " + item);
}
{
debug("Failed to evaluate " + item);
debug(e.stack);
}
if (strict) {
process.exit(1);
}
}
}
})();
const IS_CREATOR_CANON = /canon/i;
const IS_CREATOR_MS_WORD = /microsoft.*?word/i;
// just defined for better clarity or return values
const IS_SCANNED = true;
const IS_NOT_SCANNED = false;
function evalScanned(pdfdata, textLen, textPerPage) {
if (textPerPage < 300 && pdfdata.numpages>1) {
// really low number, definitelly not text pdf
return IS_SCANNED;
}
// definitelly has enough text
// might be scanned but OCRed
// we return this if no
// suspition of scanning is found
let implicitAssumption = textPerPage > 1000 ? IS_NOT_SCANNED : IS_SCANNED;
if (IS_CREATOR_CANON.test(pdfdata.info.Creator)) {
// this is always scanned, canon is brand name
return IS_SCANNED;
}
return implicitAssumption;
}
Per eseguirlo, è necessario avere installato Node.js (dovrebbe essere un singolo comando) e bisogna anche chiamare:
npm install mz pdf-parse
Uso:
node howYouNamedIt.js [scanned] [debug] [strict]
- scanned show PDFs thought to be scanned (otherwise shows not scanned)
- debug shows the debug info such as metadata and error stack traces
- strict kills the program on first error
Questo esempio non è considerato una soluzione finita, ma con l'opzione debug
si possono ottenere alcune informazioni sulle meta-informazioni di un file:
FILE: BR-L1411-3-scanned.pdf
{ PDFFormatVersion: '1.3',
IsAcroFormPresent: false,
IsXFAPresent: false,
Creator: 'Canon ',
Producer: ' ',
CreationDate: 'D:20131212150500-03'00'',
ModDate: 'D:20140709104225-03'00'' }
Metadata {
_metadata:
{ 'xmp:createdate': '2013-12-12T15:05-03:00',
'xmp:creatortool': 'Canon',
'xmp:modifydate': '2014-07-09T10:42:25-03:00',
'xmp:metadatadate': '2014-07-09T10:42:25-03:00',
'pdf:producer': '',
'xmpmm:documentid': 'uuid:79a14710-88e2-4849-96b1-512e89ee8dab',
'xmpmm:instanceid': 'uuid:1d2b2106-a13f-48c6-8bca-6795aa955ad1',
'dc:format': 'application/pdf' } }
Text length: 772
Chars per page: 2
1.10.100
D:webso-odpovedipdfBR-L1411-3-scanned.pdf
La funzione ingenua che ho scritto ha avuto un successo del 100% sui documenti che ho trovato sul mio computer (compresi i vostri esempi). Ho nominato i file in base al loro stato prima dell'esecuzione del programma, per poter vedere se i risultati sono corretti.
D:xxxxpdf>node detect_scanned.js scanned
D:xxxxpdfAR-G1002-scanned.pdf
D:xxxxpdfAR-G1002_scanned.pdf
D:xxxxpdfBR-L1411-3-scanned.pdf
D:xxxxpdfWHO_TRS_696-scanned.pdf
D:xxxxpdf>node detect_scanned.js
D:xxxxpdfAR-G1003-not-scanned.pdf
D:xxxxpdfASEE_-_thermoelectric_paper_-_final-not-scanned.pdf
D:xxxxpdfMULTIMODE ABSORBER-not-scanned.pdf
D:xxxxpdfReductionofOxideMineralsbyHydrogenPlasma-not-scanned.pdf
È possibile utilizzare la modalità di debug insieme a un minimo di programmazione per migliorare notevolmente i risultati. È possibile passare l'output del programma ad altri programmi, che avranno sempre un percorso completo per riga.
valutazioni e commenti
Se hai trovato utile il nostro articolo, ti saremmo grati se lo condividessi con altri sviluppatori e ci aiutassi a diffondere i nostri contenuti.