Apakah ada cara sederhana untuk mengidentifikasi apakah PDF dipindai?

8

Saya memiliki ribuan dokumen dan beberapa di antaranya dipindai. Jadi saya perlu skrip untuk menguji semua file PDF milik direktori. Apakah ada cara sederhana untuk melakukan itu?

  1. Sebagian besar PDF adalah laporan. Dengan demikian mereka memiliki banyak teks.
  2. Mereka sangat berbeda, tetapi yang dipindai seperti yang disebutkan di bawah ini dapat menemukan beberapa teks karena proses OCR genting ditambah dengan pemindaian.

  3. Usulan dari Sudodus dalam komentar di bawah ini tampaknya sangat menarik. Lihatlah perbedaan antara PDF yang dipindai dan yang tidak dipindai:

Dipindai:

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>

Tidak dipindai:

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>>

Jumlah gambar per halaman jauh lebih besar (sekitar satu per halaman)!

DanielTheRocketMan
sumber
7
Maksud Anda apakah itu teks atau gambar?
DK Bose
8
Mengapa Anda ingin tahu, apakah file pdf dipindai atau tidak? Bagaimana Anda bermaksud menggunakan informasi itu?
sudodus
4
@sudodus Mengajukan pertanyaan yang sangat bagus. Misalnya, sebagian besar PDF yang dipindai memiliki teks yang dapat dipilih, dikonversi menggunakan OCR. Apakah Anda membuat perbedaan antara file tersebut dan file teks? Apakah Anda tahu sumber PDF Anda?
pipa
1
Apakah ada perbedaan dalam metadata dokumen yang dipindai dan tidak dipindai? Itu akan menawarkan cara yang sangat bersih dan mudah.
hidangan penutup
1
Jika pdffile berisi gambar (dimasukkan dalam dokumen di samping teks atau sebagai seluruh halaman, 'pdf yang dipindai'), file tersebut sering (mungkin selalu) berisi string /Image/, yang dapat ditemukan dengan baris perintah grep --color -a 'Image' filename.pdf. Ini akan memisahkan file yang hanya berisi teks dari yang berisi gambar (gambar halaman penuh serta halaman teks dengan logo kecil dan gambar ilustrasi berukuran sedang).
sudodus

Jawaban:

4

Shellscript

  • Jika pdffile berisi gambar (disisipkan dalam dokumen di samping teks atau sebagai seluruh halaman, 'pdf dipindai'), file sering (mungkin selalu) berisi string /Image/.

  • Dengan cara yang sama Anda dapat mencari string /Textuntuk mengetahui apakah file pdf berisi teks (tidak dipindai).

Saya membuat shellscript pdf-text-or-image, dan itu mungkin berfungsi dalam banyak kasus dengan file Anda. Shellscript terlihat untuk string teks /Image/dan /Textdalam 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

Jadikan skrip shell dapat dieksekusi,

chmod ugo+x pdf-text-or-image

Ubah direktori ke tempat Anda memiliki pdffile dan jalankan shellscript.

File yang diidentifikasi dipindahkan ke subdirektori berikut

  • scanned
  • text
  • s-and-t (untuk dokumen dengan gambar [yang dipindai?] dan konten teks)

Objek file yang tidak dikenal, 'UFO', tetap berada di direktori saat ini.

Uji

Saya menguji shellscript dengan dua file Anda, AR-G1002.pdfdan AR-G1003.pdf, dan dengan beberapa pdffile sendiri (yang saya buat menggunakan 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

Mari kita berharap demikian

  • tidak ada UFO di set file Anda
  • penyortirannya benar tentang teks versus pindaian / gambar
sudodus
sumber
alih-alih mengarahkan ulang ke / dev / null, Anda bisa menggunakangrep -q
phuclv
1
@ phuclv, Terima kasih atas tipnya :-) Ini membuatnya agak lebih cepat juga, terutama dengan file besar, karena grep -qkeluar segera dengan status nol jika ada kecocokan yang ditemukan (alih-alih mencari seluruh file).
sudodus
6
  1. Letakkan semua file .pdf dalam satu folder.
  2. Tidak ada file .txt di folder itu.
  3. Di terminal ganti direktori ke folder itu dengan cd <path to dir>
  4. Buat satu direktori lagi untuk file yang tidak dipindai. Contoh:
mkdir ./x 
for file in *.pdf; do
    if [ $(pdftotext "$file")"x" == "x" ] ; then mv "$file" ./x; fi
rm *.txt
done

Semua file pdf yang dipindai akan tetap berada di folder dan file lain akan pindah ke folder lain.

Vijay
sumber
ini bagus. Namun, file ini pergi ke folder lain dan dipindai: drive.google.com/open?id=12xIQdRo_cyTf27Ck6DQKvRyRvlkYEzjl Apa yang terjadi?
DanielTheRocketMan
8
PDF yang dipindai sering selalu berisi konten teks OCR, jadi saya rasa tes sederhana akan gagal untuk mereka. Indikator yang lebih baik mungkin satu gambar besar per halaman, terlepas dari konten teks.
Joey
2
Diturunkan karena cacat yang sangat jelas: bagaimana Anda tahu jika file dipindai atau tidak di tempat pertama? Itulah yang ditanyakan oleh OP: bagaimana menguji secara terprogram untuk dipindai atau tidak.
jamesqf
1
@DanielTheRocketMan Versi file PDF kemungkinan memiliki dampak pada alat yang Anda gunakan untuk memilih teks. Output file pdf-filename.pdfakan menghasilkan nomor versi. Saya tidak dapat mencari teks tertentu di BR-L1411-3.pdf BR-L1411-3.pdf: dokumen PDF, versi 1.3 tetapi dapat mencari teks di kedua file lain yang Anda berikan, yaitu versi 1.5 dan 1.6 dan dapatkan satu atau lebih kecocokan. Saya menggunakan penampil PDF XChange untuk mencari file-file ini tetapi memiliki hasil yang sama dengan evince. dokumen versi 1.3 tidak cocok dengan apa pun.
Penatua Geek
1
@DanielTheRocketMan Jika itu masalahnya, Anda mungkin menemukan mengurutkan dokumen berdasarkan versi menggunakan hasil dari filemembantu dalam menyelesaikan proyek Anda. Meskipun saya sepertinya orang lain masih tidak jelas tentang apa yang ingin Anda capai.
Penatua Geek
2

Saya membuat skrip untuk mendeteksi apakah PDF itu OCRd. Gagasan utama: Dalam OCRd PDF adalah teks tidak terlihat.

Algoritma untuk menguji apakah PDF yang diberikan ( f1) adalah OCRd:

  1. buat salinan f1catatan sebagaif2
  2. hapus semua teks f2
  3. buat gambar (PNG) untuk semua (atau hanya beberapa) halaman untuk f1danf2
  4. f1adalah OCRd jika semua gambar f1dan f2identik.

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
Johannes Filter
sumber
1

Hobbyist menawarkan solusi yang baik jika dokumen yang dipindai koleksi dokumen tidak memiliki teks yang ditambahkan dengan optical character recognition (OCR). Jika ini suatu kemungkinan, Anda mungkin ingin melakukan beberapa skrip yang membaca output pdfinfo -metadan memeriksa alat yang digunakan untuk membuat file, atau menggunakan rutin Python yang menggunakan salah satu pustaka Python untuk memeriksanya. Mencari teks dengan alat seperti stringsini tidak akan dapat diandalkan karena konten PDF dapat dikompresi. Dan memeriksa alat pembuatan juga tidak aman, karena halaman PDF dapat digabungkan; Saya secara rutin menggabungkan dokumen teks PDF dengan gambar yang dipindai untuk menyatukan semuanya.

Maaf saya tidak dapat menawarkan saran khusus. Sudah lama sejak saya melihat struktur internal PDF, tetapi tergantung pada seberapa ketat persyaratan Anda, Anda mungkin ingin tahu bahwa itu agak rumit. Semoga berhasil!

ichabod
sumber
2
Saya juga mencoba menggunakan python, tetapi tidak sepele untuk mengetahui apakah pdf dipindai atau tidak. Intinya adalah bahwa bahkan dokumen yang Anda tidak dapat memilih teks menyajikan beberapa teks ketika itu dikonversi ke txt. Misalnya, saya menggunakan penambang pdf dalam Python dan saya dapat menemukan beberapa teks dalam konversi bahkan untuk pdf yang alat pilih tidak bekerja.
DanielTheRocketMan
1

Jika ini lebih tentang mendeteksi apakah PDF dibuat dengan memindai daripada pdf memiliki gambar daripada teks maka Anda mungkin perlu menggali metadata file, bukan hanya konten.

Secara umum, untuk file yang dapat saya temukan di komputer saya dan file pengujian Anda, berikut ini benar:

  • File yang dipindai memiliki kurang dari 1000chars / halaman vs. yang tidak dipindai yang selalu memiliki lebih dari 1000chars / halaman
  • Beberapa file pindaian independen memiliki "Canon" terdaftar sebagai pencipta PDF, mungkin merujuk perangkat lunak pemindai Canon
  • PDF dengan "Microsoft Word" sebagai pembuat kemungkinan tidak akan dipindai, karena merupakan kata ekspor. Tetapi seseorang dapat memindai kata, lalu mengekspor ke PDF - beberapa orang memiliki alur kerja yang sangat aneh .

Saya menggunakan Windows saat ini, jadi saya menggunakan node.jscontoh berikut:

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;
}

Untuk menjalankannya, Anda harus menginstal Node.js (harus berupa satu perintah) dan Anda juga perlu memanggil:

npm install mz pdf-parse

Pemakaian:

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

Contoh ini tidak dianggap sebagai solusi selesai, tetapi dengan debugflag, Anda mendapatkan beberapa informasi meta informasi 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

Fungsi naif yang saya tulis memiliki kesuksesan 100% pada dokumen yang dapat saya temukan di komputer saya (termasuk sampel Anda). Saya memberi nama file berdasarkan status mereka sebelum menjalankan program, untuk memungkinkan untuk melihat apakah hasilnya benar.

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

Anda dapat menggunakan mode debug bersama dengan sedikit pemrograman untuk meningkatkan hasil Anda. Anda dapat meneruskan output program ke program lain, ia akan selalu memiliki satu jalur penuh per baris.

Tomáš Zato - Pasang kembali Monica
sumber
Re "Microsoft Word" sebagai pembuat, itu akan tergantung pada sumber dokumen asli. Misalnya, mereka adalah karya ilmiah, banyak jika tidak sebagian besar akan dibuat oleh sesuatu di toolchain LaTeX.
jamesqf
0

2 cara yang bisa saya pikirkan:

  1. Menggunakan alat teks pilih: jika Anda menggunakan PDF yang dipindai, teks tidak dapat dipilih, melainkan sebuah kotak akan muncul. Anda dapat menggunakan fakta ini untuk membuat skrip. Saya tahu di C ++ QT ada cara, tidak yakin di Linux sekalipun.

  2. Mencari kata dalam file: Dalam PDF yang tidak dipindai, pencarian Anda akan berfungsi, namun tidak dalam file yang dipindai. Anda hanya perlu menemukan beberapa kata yang umum untuk semua PDF atau saya lebih suka mengatakan mencari huruf 'e' di semua PDF. Ini memiliki distribusi frekuensi tertinggi sehingga kemungkinan Anda akan menemukannya di semua dokumen yang memiliki teks (Kecuali itu gadsby )

misalnya

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

Gunakan salah satu alat pemrosesan teks

swapedoc
sumber
1
PDF yang dipindai juga dapat memiliki teks yang dapat dipilih karena OCR bukan hal yang aneh saat ini dan bahkan banyak pembaca PDF gratis memiliki fitur OCR
phuclv
@ phuclv: Tetapi jika file itu dikonversi ke teks dengan OCR, itu bukan lagi file "dipindai", setidaknya seperti yang saya pahami tujuan OP. Meskipun sebenarnya Anda sekarang memiliki 3 jenis file pdf: teks ab initio, teks dari OCR, dan "teks" yang merupakan gambar yang dipindai.
jamesqf
1
@jamesqf silakan lihat contoh di atas. Mereka dipindai pdf. Sebagian besar teks saya tidak dapat mengambil menggunakan pdfminer konvensional.
DanielTheRocketMan
1
saya pikir op perlu memikirkan kembali / ulangi definisi yang dipindai dalam kasus ini atau berhenti menggunakan acrobat x, yang mengambil salinan yang dipindai dan menganggapnya sebagai ocr daripada gambar
swapedoc