Esiste un modo semplice per identificare se un PDF viene digitalizzato?


8

Ho migliaia di documenti e alcuni di loro sono scannerizzati. Quindi ho bisogno di uno script per testare tutti i file PDF che appartengono a una directory. C'è un modo semplice per farlo?

  1. La maggior parte dei PDF sono rapporti. Quindi hanno molto testo.
  2. Sono molto diversi, ma quelli scansionati come menzionato di seguito possono trovare del testo a causa di un precario processo OCR accoppiato alla scansione.

  3. La proposta dovuta a Sudodus nei commenti che seguono sembra essere molto interessante. Guarda la differenza tra un PDF scansionato e uno non scansionato:

Scanned:

grep --color -a 'Image' AR-G1002.pdf
<</BitsPerComponent 8/ColorSpace/DeviceRGB/Filter[/DCTDecode]/Height 2197/Length 340615/Name/Obj13/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 1/ColorSpace/DeviceGray/DecodeParms<</Columns 1698/K -1>>/Filter/CCITTFaxDecode/Height 2197/Length 40452/Name/Obj18/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 1/ColorSpace/DeviceGray/DecodeParms<</Columns 1698/K -1>>/Filter/CCITTFaxDecode/Height 2197/Length 41680/Name/Obj23/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 1/ColorSpace/DeviceGray/DecodeParms<</Columns 1698/K -1>>/Filter/CCITTFaxDecode/Height 2197/Length 41432/Name/Obj28/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 1/ColorSpace/DeviceGray/DecodeParms<</Columns 1698/K -1>>/Filter/CCITTFaxDecode/Height 2197/Length 59084/Name/Obj33/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 8/ColorSpace/DeviceRGB/Filter[/DCTDecode]/Height 2197/Length 472681/Name/Obj38/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 8/ColorSpace/DeviceRGB/Filter[/DCTDecode]/Height 2197/Length 469340/Name/Obj43/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 8/ColorSpace/DeviceRGB/Filter[/DCTDecode]/Height 2197/Length 371863/Name/Obj48/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 8/ColorSpace/DeviceRGB/Filter[/DCTDecode]/Height 2197/Length 344092/Name/Obj53/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 1/ColorSpace/DeviceGray/DecodeParms<</Columns 1698/K -1>>/Filter/CCITTFaxDecode/Height 2197/Length 59416/Name/Obj58/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 1/ColorSpace/DeviceGray/DecodeParms<</Columns 1698/K -1>>/Filter/CCITTFaxDecode/Height 2197/Length 48308/Name/Obj63/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 1/ColorSpace/DeviceGray/DecodeParms<</Columns 1698/K -1>>/Filter/CCITTFaxDecode/Height 2197/Length 51564/Name/Obj68/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 1/ColorSpace/DeviceGray/DecodeParms<</Columns 1698/K -1>>/Filter/CCITTFaxDecode/Height 2197/Length 63184/Name/Obj73/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 1/ColorSpace/DeviceGray/DecodeParms<</Columns 1698/K -1>>/Filter/CCITTFaxDecode/Height 2197/Length 40824/Name/Obj78/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 1/ColorSpace/DeviceGray/DecodeParms<</Columns 1698/K -1>>/Filter/CCITTFaxDecode/Height 2197/Length 23320/Name/Obj83/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 1/ColorSpace/DeviceGray/DecodeParms<</Columns 1698/K -1>>/Filter/CCITTFaxDecode/Height 2197/Length 31504/Name/Obj93/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 1/ColorSpace/DeviceGray/DecodeParms<</Columns 1698/K -1>>/Filter/CCITTFaxDecode/Height 2197/Length 18996/Name/Obj98/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 8/ColorSpace/DeviceRGB/Filter[/DCTDecode]/Height 2197/Length 292932/Name/Obj103/Subtype/Image/Type/XObject/Width 1698>>stream
<</BitsPerComponent 1/ColorSpace/DeviceGray/DecodeParms<</Columns 1698/K -1>>/Filter/CCITTFaxDecode/Height 2197/Length 27720/Name/Obj108/Subtype/Image/Type/XObject/Width 1698>>stream
               <rdf:li xml:lang="x-default">Image</rdf:li>
               <rdf:li xml:lang="x-default">Image</rdf:li>

Non scansionato:

grep --color -a 'Image' AR-G1003.pdf
<</Lang(en-US)/MarkInfo<</Marked true>>/Metadata 167 0 R/Pages 2 0 R/StructTreeR<</Contents 4 0 R/Group<</CS/DeviceRGB/S/Transparency/Type/Group>>/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<</Font<</F1 5 0 R/F2 7 0 R/F3 9 0 R/F4 11 0 R/F5 13 0 R>>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI]>>/StructParents 0/Tabs/S/Type/<</Filter/FlateDecode/Length 5463>>stream
<</BaseFont/Times#20New#20Roman,Bold/Encoding/WinAnsiEncoding/FirstChar 32/FontD<</Ascent 891/AvgWidth 427/CapHeight 677/Descent -216/Flags 32/FontBBox[-558 -216 2000 677]/FontName/Times#20New#20Roman,Bold/FontWeight 700/ItalicAngle 0/Leadi<</BaseFont/Times#20New#20Roman/Encoding/WinAnsiEncoding/FirstChar 32/FontDescri<</Ascent 891/AvgWidth 401/CapHeight 693/Descent -216/Flags 32/FontBBox[-568 -216 2000 693]/FontName/Times#20New#20Roman/FontWeight 400/ItalicAngle 0/Leading 42<</BaseFont/Arial,Bold/Encoding/WinAnsiEncoding/FirstChar 32/FontDescriptor 10 0<</Ascent 905/AvgWidth 479/CapHeight 728/Descent -210/Flags 32/FontBBox[-628 -210 2000 728]/FontName/Arial,Bold/FontWeight 700/ItalicAngle 0/Leading 33/MaxWidth<</BaseFont/Times#20New#20Roman,Italic/Encoding/WinAnsiEncoding/FirstChar 32/FontDescriptor 12 0 R/LastChar 118/Name/F4/Subtype/TrueType/Type/Font/Widths 164 0 <</Ascent 891/AvgWidth 402/CapHeight 694/Descent -216/Flags 32/FontBBox[-498 -216 1333 694]/FontName/Times#20New#20Roman,Italic/FontWeight 400/ItalicAngle -16.4<</BaseFont/Arial/Encoding/WinAnsiEncoding/FirstChar 32/FontDescriptor 14 0 R/La<</Ascent 905/AvgWidth 441/CapHeight 728/Descent -210/Flags 32/FontBBox[-665 -210 2000 728]/FontName/Arial/FontWeight 400/ItalicAngle 0/Leading 33/MaxWidth 2665<</Contents 16 0 R/Group<</CS/DeviceRGB/S/Transparency/Type/Group>>/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<</Font<</F1 5 0 R/F2 7 0 R/F5 13 0 R>>/ProcSet[<</Filter/FlateDecode/Length 7534>>streamarents 1/Tabs/S/Type/Page>>
<</Contents 18 0 R/Group<</CS/DeviceRGB/S/Transparency/Type/Group>>/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<</Font<</F1 5 0 R/F2 7 0 R/F5 13 0 R>>/ProcSet[<</Filter/FlateDecode/Length 6137>>streamarents 2/Tabs/S/Type/Page>>
<</Contents 20 0 R/Group<</CS/DeviceRGB/S/Transparency/Type/Group>>/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<</Font<</F1 5 0 R/F2 7 0 R/F5 13 0 R/F6 21 0 R><</Filter/FlateDecode/Length 6533>>stream>>/StructParents 3/Tabs/S/Type/Page>>
<</BaseFont/Times#20New#20Roman/DescendantFonts 22 0 R/Encoding/Identity-H/Subty<</BaseFont/Times#20New#20Roman/CIDSystemInfo 24 0 R/CIDToGIDMap/Identity/DW 100<</Ascent 891/AvgWidth 401/CapHeight 693/Descent -216/Flags 32/FontBBox[-568 -216 2000 693]/FontFile2 160 0 R/FontName/Times#20New#20Roman/FontWeight 400/Italic<</Contents 27 0 R/Group<</CS/DeviceRGB/S/Transparency/Type/Group>>/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<</ExtGState<</GS28 28 0 R/GS29 29 0 R>>/Font<</F1 5 0 R/F2 7 0 R/F3 9 0 R/F5 13 0 R/F6 21 0 R>>/ProcSet[/PDF/Text/ImageB/ImageC<</Filter/FlateDecode/Length 5369>>streamge>>

Il numero di immagini per pagina è molto più grande (circa uno per pagina)!


7
Vuoi dire se sono testo o immagini?
DK Bose,

8
Perché vuoi sapere se un file pdf viene scannerizzato o no? Come intendi utilizzare tali informazioni?
sudodus,

4
@sudodus Fa un'ottima domanda. Ad esempio, molti PDF scansionati hanno il loro testo disponibile per la selezione, convertito tramite OCR. Fai la differenza tra tali file e file di testo? Non si conosce l'origine dei tuoi file PDF?
pipe

1
C'è qualche differenza nei metadati dei documenti scansionati e non scansionati? Ciò offrirebbe un modo molto semplice e pulito.
dessert

1
Se un pdffile 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/, che può essere trovata nella riga di comando grep --color -a 'Image' filename.pdf. Ciò separerà i file che contengono solo testo da quelli contenenti immagini (immagini a pagina intera e pagine di testo con piccoli loghi e immagini illustrative di medie dimensioni).
sudodus,

Risposte:


4

shellscript

  • Se un pdffile contiene un'immagine (inserita in un documento accanto a testo o come pagine intere, "PDF scansionato"), il file spesso (forse sempre) contiene la stringa /Image/.

  • Allo stesso modo puoi cercare la stringa /Textper dire se un file pdf contiene testo (non scansionato).

Ho creato lo shellscript pdf-text-or-imagee potrebbe funzionare nella maggior parte dei casi con i tuoi file. Lo shellscript cerca le stringhe di testo /Image/e /Textnei pdffile.

#!/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

Rendi eseguibile lo shellscript,

chmod ugo+x pdf-text-or-image

pdfPassa alla directory in cui hai i file ed esegui lo shellscript.

I file identificati vengono spostati nelle seguenti sottodirectory

  • scanned
  • text
  • s-and-t (per documenti con entrambe le immagini [scansionate?] e il contenuto del testo)

Gli oggetti file non identificati, "UFO", rimangono nella directory corrente.

Test

Ho testato lo shellscript con due dei tuoi file AR-G1002.pdfe AR-G1003.pdf, e con alcuni pdffile (che ho creato usando 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 sono UFO nel tuo set di file
  • l'ordinamento è corretto per quanto riguarda il testo rispetto a scansioni / immagini

invece di reindirizzare a / dev / null puoi semplicemente usaregrep -q
phuclv

1
@phuclv, Grazie per il suggerimento :-) Questo rende anche un po 'più veloce, in particolare con file di grandi dimensioni, perché grep -qesce immediatamente con stato zero se viene trovata una corrispondenza (anziché cercare tutti i file).
sudodus,

6
  1. Metti tutti i file .pdf in una cartella.
  2. Nessun file .txt in quella cartella.
  3. Nel terminale cambia la directory in quella cartella con cd <path to dir>
  4. Crea un'altra directory per i file non sottoposti a scansione. Esempio:
mkdir ./x 
for file in *.pdf; do
    if [ $(pdftotext "$file")"x" == "x" ] ; then mv "$file" ./x; fi
rm *.txt
done

Tutti i file scansionati in pdf rimarranno nella cartella e gli altri file si sposteranno in un'altra cartella.


è fantastico Tuttavia, questo file va nell'altra cartella e viene scansionato: drive.google.com/open?id=12xIQdRo_cyTf27Ck6DQKvRyRvlkYEzjl Che cosa sta succedendo?
DanielTheRocketMan

8
I PDF scansionati spesso contengono sempre il contenuto del testo OCR, quindi immagino che un semplice test fallirebbe per loro. Un indicatore migliore potrebbe essere un'immagine di grandi dimensioni per pagina, indipendentemente dal contenuto del testo.
Joey,

2
Sottovalutato a causa del difetto molto evidente: come fai a sapere se i file vengono scansionati o no in primo luogo? Questo è ciò che l'OP sta chiedendo: come testare a livello di codice per la scansione o meno.
jamesqf,

1
@DanielTheRocketMan È probabile che la versione del file PDF abbia un impatto sullo strumento utilizzato per selezionare il testo. L'output di file pdf-filename.pdfprodurrà un numero di versione. Non sono riuscito a cercare un testo specifico in BR-L1411-3.pdf BR-L1411-3.pdf: documento PDF, versione 1.3, ma sono stato in grado di cercare testo in entrambi gli altri file forniti, che sono la versione 1.5 e 1.6 e ottieni una o più partite. Ho usato il visualizzatore XChange PDF per cercare questi file ma ho avuto risultati simili con evince. il documento versione 1.3 non corrisponde a nulla.
Elder Geek,

1
@DanielTheRocketMan In questo caso potresti trovare l'ordinamento dei documenti per versione usando l'output di fileutile per completare il tuo progetto. Anche se io, come sembra, gli altri non sono ancora chiari su ciò che stai tentando di realizzare.
Elder Geek,

2

Ho creato uno script per rilevare se un PDF era OCRd. L'idea principale: nei PDF OCRd il testo è invisibile.

Algoritmo per verificare se un determinato PDF ( f1) era OCRd:

  1. creare una copia di f1annotato comef2
  2. elimina tutto il testo f2
  3. creare immagini (PNG) per tutte (o solo alcune) pagine per f1ef2
  4. f1era OCRd se tutte le immagini di f1e f2sono identiche.

https://github.com/jfilter/pdf-scripts/blob/master/is_ocrd_pdf.sh

#!/usr/bin/env bash
set -e
set -x

################################################################################
# Check if a PDF was scanned or created digitally, works on OCRd PDFs
#
# Usage:
#   bash is_scanned_pdf.sh [-p] file
#
#   Exit 0: Yes, file is a scanned PDF
#   Exit 99: No, file was created digitally
#
# Arguments:
#   -p or --pages: pos. integer, only consider first N pages
#
# Please report issues at https://github.com/jfilter/pdf-scripts/issues
#
# GPLv3, Copyright (c) 2020 Johannes Filter
################################################################################

# parse arguments
# h/t https://stackoverflow.com/a/33826763/4028896
max_pages=-1
# skip over positional argument of the file(s), thus -gt 1
while [[ "$#" -gt 1 ]]; do
  case $1 in
  -p | --pages)
    max_pages="$2"
    shift
    ;;
  *)
    echo "Unknown parameter passed: $1"
    exit 1
    ;;
  esac
  shift
done

# increment to make it easier with page numbering
max_pages=$((max_pages++))

command_exists() {
  if ! [ -x $($(command -v $1 &>/dev/null)) ]; then
    echo $(error: $1 is not installed.) >&2
    exit 1
  fi
}

command_exists mutool && command_exists gs && command_exists compare
command_exists pdfinfo

orig=$PWD
num_pages=$(pdfinfo $1 | grep Pages | awk '{print $2}')

echo $num_pages

echo $max_pages

if ((($max_pages > 1) && ($max_pages < $num_pages))); then
  num_pages=$max_pages
fi

cd $(mktemp -d)

for ((i = 1; i <= num_pages; i++)); do
  mkdir -p output/$i && echo $i
done

# important to filter text on output of GS (tmp1), cuz GS alters input PDF...
gs -o tmp1.pdf -sDEVICE=pdfwrite -dLastPage=$num_pages $1 &>/dev/null
gs -o tmp2.pdf -sDEVICE=pdfwrite -dFILTERTEXT tmp1.pdf &>/dev/null
mutool convert -o output/%d/1.png tmp1.pdf 2>/dev/null
mutool convert -o output/%d/2.png tmp2.pdf 2>/dev/null

for ((i = 1; i <= num_pages; i++)); do
  echo $i
  # difference in pixels, if 0 there are the same pictures
  # discard diff image
  if ! compare -metric AE output/$i/1.png output/$i/2.png null: 2>&1; then
    echo " pixels difference, not a scanned PDF, mismatch on page $i"
    exit 99
  fi
done

1

Hobbyist offre una buona soluzione se ai documenti scansionati della raccolta documenti non è stato aggiunto testo con riconoscimento ottico dei caratteri (OCR). Se questa è una possibilità, potresti voler eseguire alcuni script che leggono l'output pdfinfo -metae controllano lo strumento utilizzato per creare il file o impiegano una routine Python che utilizza una delle librerie Python per esaminarli. La ricerca di testo con uno strumento simile stringsnon sarà affidabile perché il contenuto PDF può essere compresso. E il controllo dello strumento di creazione non è neanche sicuro, poiché le pagine PDF possono essere combinate; Combino abitualmente documenti di testo PDF con immagini scansionate per tenere insieme le cose.

Mi dispiace di non essere in grado di offrire suggerimenti specifici. È passato un po 'di tempo da quando ho dato un'occhiata alla struttura interna del PDF, ma a seconda di quanto siano rigorosi i tuoi requisiti, potresti voler sapere che è un po' complicato. In bocca al lupo!


2
Sto anche provando a usare Python, ma non è banale sapere se un pdf viene scansionato o meno. Il punto è che anche i documenti che non è possibile selezionare testo presentano del testo quando viene convertito in txt. Ad esempio, sto usando pdf miner in Python e posso trovare del testo nella conversione anche per i pdf che lo strumento di selezione non funziona.
DanielTheRocketMan

1

Se si tratta più di rilevare effettivamente se il PDF è stato creato mediante la scansione piuttosto che il pdf ha immagini anziché testo , potrebbe essere necessario scavare nei metadati del file, non solo nel contenuto.

In generale, per i file che ho trovato sul mio computer e sui file di test, è vero quanto segue:

  • I file scansionati hanno meno di 1000 car / pagina rispetto a quelli non scansionati che hanno sempre più di 1000 car / pagina
  • Più file scansionati indipendenti avevano "Canon" elencato come il creatore di PDF, facendo probabilmente riferimento al software dello scanner Canon
  • È probabile che i PDF con "Microsoft Word" come creatore non vengano sottoposti a scansione, poiché sono esportazioni di parole. Ma qualcuno potrebbe scansionare su Word, quindi esportare in PDF - alcune persone hanno un flusso di lavoro molto strano .

Al momento sto usando Windows, quindi ho usato node.jsper 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("\n\nFILE: ", 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, devi avere Node.js installato (dovrebbe essere un singolo comando) e devi 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 il debugflag puoi 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:\web\so-odpovedi\pdf\BR-L1411-3-scanned.pdf

L'ingenua funzione che ho scritto ha successo al 100% sui documenti che ho potuto trovare sul mio computer (compresi i tuoi campioni). Ho chiamato i file in base al loro stato prima di eseguire il programma, per rendere possibile vedere se i risultati sono corretti.

D:\xxxx\pdf>node detect_scanned.js scanned
D:\xxxx\pdf\AR-G1002-scanned.pdf
D:\xxxx\pdf\AR-G1002_scanned.pdf
D:\xxxx\pdf\BR-L1411-3-scanned.pdf
D:\xxxx\pdf\WHO_TRS_696-scanned.pdf

D:\xxxx\pdf>node detect_scanned.js
D:\xxxx\pdf\AR-G1003-not-scanned.pdf
D:\xxxx\pdf\ASEE_-_thermoelectric_paper_-_final-not-scanned.pdf
D:\xxxx\pdf\MULTIMODE ABSORBER-not-scanned.pdf
D:\xxxx\pdf\ReductionofOxideMineralsbyHydrogenPlasma-not-scanned.pdf

È possibile utilizzare la modalità di debug insieme a un po 'di programmazione per migliorare notevolmente i risultati. È possibile passare l'output del programma ad altri programmi, avrà sempre un percorso completo per riga.


Ri "Microsoft Word" come creatore, dipenderà dalla fonte dei documenti originali. Se per esempio sono articoli scientifici, molti se non molti saranno stati creati da qualcosa nella toolchain di LaTeX.
jamesqf,

0

2 modi in cui posso pensare:

  1. Usando lo strumento di selezione del testo: se stai usando un PDF scansionato i testi non possono essere selezionati, piuttosto apparirà una casella. È possibile utilizzare questo fatto per creare lo script. So che in C ++ QT c'è un modo, non sono sicuro in Linux però.

  2. Cerca parola nel file: in un PDF non digitalizzato la ricerca funzionerà, tuttavia non nel file digitalizzato. Devi solo trovare alcune parole comuni a tutti i PDF o preferirei cercare la lettera "e" in tutti i PDF. Ha la più alta distribuzione di frequenza, quindi è probabile che lo troverai in tutti i documenti che hanno testo (A meno che non sia un gadget )

per esempio

grep -rnw '/path/to/pdf/' -e 'e'

Utilizzare uno degli strumenti di elaborazione del testo


1
un PDF scansionato può anche avere testi selezionabili perché l'OCR non è una cosa strana al giorno d'oggi e anche molti lettori PDF gratuiti hanno la funzione OCR
phuclv

@phuclv: Ma se il file è stato convertito in testo con OCR, non è più un file "scansionato", almeno per quanto ho capito lo scopo del PO. Anche se davvero avresti ora 3 tipi di file pdf: text ab initio, text from OCR e "text" che è un'immagine digitalizzata.
jamesqf,

1
@jamesqf, guarda l'esempio sopra. Sono PDF scansionati. La maggior parte del testo che non riesco a recuperare utilizzando un pdfminer convenzionale.
DanielTheRocketMan,

1
penso che l'operazione debba ripensare / riformulare la definizione di scannerizzata in quel caso o smettere di usare acrobat x, che prende la copia digitalizzata e la prende come un ocr piuttosto che come immagine
scambiata il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.