Porównanie plików PDF w Linuksie

Szukam linuksowego narzędzia wiersza poleceń do porównywania dwóch plików PDF i zapisywania różnic do pliku wyjściowego PDF. Narzędzie powinno tworzyć diff-pdf w procesie wsadowym. Pliki PDF to plany budowy, więc czysty tekst-porównanie nie działa.

Coś w stylu:

<tool> file1.pdf file2.pdf -o diff-out.pdf

Większość znalezionych narzędzi konwertuje pliki PDF na obrazy i porównuje je, ale tylko z GUI.

Każde inne rozwiązanie jest również mile widziane.

Author: Kurt Pfeifle, 2011-06-24

3 answers

Napisałem własny scenariusz, który robi coś podobnego do tego, o co prosisz. Skrypt wykorzystuje 4 narzędzia, aby osiągnąć swój cel:

  1. polecenie ImageMagick compare
  2. Narzędzie pdftk (Jeśli masz wielostronicowe pliki PDF)
  3. Ghostscript (opcjonalnie)
  4. md5sum (opcjonalnie)

Powinno być dość łatwe przeniesienie tego pliku do pliku wsadowego .bat Dla DOS/Windows.

Ale najpierw, proszę zauważyć: to działa dobrze tylko w przypadku plików PDF, które mają ten sam rozmiar strony / nośnika. Porównanie odbywa się piksel po pikselu między dwoma wejściowymi plikami PDF. Plik wynikowy jest obrazkiem pokazującym "diff" w następujący sposób:

  • każdy piksel, który pozostaje niezmieniony, staje się biały.
  • każdy zmieniony piksel jest pomalowany na Czerwono.

Ten obraz różnicowy jest zapisywany jako nowy plik PDF, aby był lepiej dostępny na różnych platformach systemu operacyjnego.

Używam tego na przykład, aby odkryć minimalne różnice wyświetlania strony, gdy czcionka zastępowanie w przetwarzaniu plików PDF wchodzi w grę.

Może się zdarzyć, że nie ma widocznej różnicy między plikami PDF, chociaż różnią się one HASHAMI MD5 i / lub rozmiarem pliku. W takim przypadku wyjściowa strona PDF "diff" stanie się biała. Możesz automatycznie wykryć ten warunek, więc musisz tylko wizualnie zbadać nie-białe pliki PDF, usuwając automatycznie wszystkie białe.

Oto klocki:

Pdftk

Użyj tego narzędzie wiersza poleceń do dzielenia wielostronicowych plików PDF na wiele pojedynczych plików PDF:

pdftk  file_1.pdf  burst  output  somewhere/file_1---page_%03d.pdf
pdftk  file_2.pdf  burst  output  somewhere/file_2---page_%03d.pdf

Jeśli porównujesz tylko 1-stronicowe pliki PDF, ten element jest opcjonalny. Ponieważ mówisz o "planach budowlanych", jest to prawdopodobnie przypadek.

Porównaj

Użyj tego narzędzia wiersza poleceń z ImageMagick, aby utworzyć stronę PDF "diff"dla każdej ze stron:

compare \
       -verbose \
       -debug coder \
       -log "%u %m:%l %e" \
        somewhere/file_1---page_001.pdf \
        somewhere/file_2---page_001.pdf \
       -compose src \
        somewhereelse/file_1--file_2---diff_page_001.pdf

Ghostscript

Z powodu automatycznie wstawianych metadanych (takich jak aktualna data+godzina), PDF wyjście nie działa dobrze dla porównań plików opartych na MD5hash.

Jeśli chcesz automatycznie wykrywać wszystkie przypadki, w których diff PDF składa się z czysto białej strony, powinieneś przekonwertować stronę PDF do darmowego formatu bitmapowego metadanych za pomocą urządzenia wyjściowego bmp256. Możesz to zrobić tak:

Najpierw dowiedz się, jaki jest format rozmiaru strony Twojego pliku PDF. Ponownie, to małe narzędzie identify jest częścią każdej instalacji ImageMagick:

 identify \
   -format "%[fx:(w)]x%[fx:(h)]" \
    somewhereelse/file_1--file_2---diff_page_001.pdf

Możesz zapisać tę wartość w zmiennej środowiskowej takiej jak ta:

 export my_size=$(identify \
   -format "%[fx:(w)]x%[fx:(h)]" \
    somewhereelse/file_1--file_2---diff_page_001.pdf)

Teraz Ghostscript wchodzi w grę, używając wiersza poleceń, który zawiera wykryty powyżej rozmiar strony, ponieważ jest przechowywany w zmiennej:

 gs \
   -o somewhereelse/file_1--file_2---diff_page_001.ppm \
   -sDEVICE=ppmraw \
   -r72 \
   -g${my_size} \
    somewhereelse/file_1--file_2---diff_page_001.pdf

To daje PPM (Portable PixMap) z rozdzielczością 72 dpi z oryginalnej strony PDF. 72 dpi zwykle wystarcza na to, czego chcemy... Następnie utwórz czysto białą stronę PPM o tym samym rozmiarze strony:

 gs \
   -o somewhereelse/file_1--file_2---whitepage_001.ppm \
   -sDEVICE=ppmraw \
   -r72 \
   -g${my_size} \
   -c "showpage"

Część -c "showpage" jest poleceniem Postscriptowym, które mówi Ghostscript emitujący tylko pustą stronę.

Suma MD5

Użyj skrótu MD5, aby automatycznie porównać oryginalne PPM z białymi stronami PPM. Jeśli są takie same, można bezpiecznie założyć, że nie ma różnic między plikami PDF i dlatego zmienić nazwę lub usunąć diff-PDF: {]}

 MD5_1=$(md5sum somewhereelse/file_1--file_2---diff_page_001.ppm | awk '{print $1}')
 MD5_2=$(md5sum somewhereelse/file_1--file_2---whitepage_001.ppm | awk '{print $1}')

 if [ "x${MD5_1}" == "x${MD5_2}" ]; then 
     mv  \
       somewhereelse/file_1--file_2---diff_page_001.pdf \
       somewhereelse/file_1--file_2---NODIFFERENCE_page_001.pdf # rename all-white PDF
     rm  \
       somewhereelse/file_1--file_2---*_page_001.ppm            # delete both PPMs
 fi

Pozwala to uniknąć wizualnej kontroli "plików PDF różniących się od siebie", które nie mają żadnych różnic.

 35
Author: Kurt Pfeifle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-27 14:24:30

Oto hack, aby to zrobić.

pdftotext file1.pdf
pdftotext file2.pdf
diff file1.txt file2.txt
 24
Author: xevincent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-24 15:34:30

Zrobione w 2 linijkach z (allmighty) imagemagick i pdftk:

compare -verbose -debug coder $PDF_1 $PDF_2 -compose src $OUT_FILE.tmp
pdftk $OUT_FILE.tmp background $PDF_1 output $OUT_FILE

Opcje-verbose i-debug są opcjonalne.

  • compare tworzy plik PDF z diffem jako czerwone piksele.
  • pdftk łączy diff-pdf z tłem PDF_1
 5
Author: Christof Aenderl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-23 14:08:45