PDF在linux命令行上进行比较

时间:2011-06-24 14:22:03

标签: linux pdf comparison ghostscript

我正在寻找一个Linux命令行工具来比较两个PDF文件并将差异保存为PDF文件。该工具应该在批处理过程中创建diff-pdf。 PDF文件是构造计划,因此纯文本比较不起作用。

类似的东西:

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

我发现的大多数工具都将PDF转换为图像并进行比较,但只能使用GUI。

欢迎任何其他解决方案。

3 个答案:

答案 0 :(得分:39)

我编写了自己的脚本,它的功能类似于您所要求的内容。该脚本使用4个工具来实现其目标:

  1. ImageMagick的compare命令
  2. pdftk实用程序(如果您有多页PDF)
  3. Ghostscript(可选)
  4. md5sum(可选)
  5. 将其移植到DOS / Windows的.bat批处理文件中应该很容易。

    但首先请注意:这仅适用于页面/媒体大小相同的PDF。比较在两个输入PDF之间逐个像素地完成。生成的文件是一个显示“diff”的图像,如下所示:

    • 保持不变的每个像素变为白色。
    • 每个变化的像素都涂成红色。

    该差异图像保存为新的PDF,以便在不同的操作系统平台上更好地访问。

    我正在使用它来发现PDF处理中的字体替换发挥作用时的最小页面显示差异。

    虽然它们在MD5哈希值和/或文件大小上有所不同,但您的PDF之间可能没有明显差异。在这种情况下,“diff”输出PDF页面将变为全白。您可以自动发现这种情况,因此您只需通过自动删除全白PDF来直观地调查非白色PDF。

    以下是构建基块:

    PDFTK

    使用此命令行实用程序将多页PDF文件拆分为多个单页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
    

    如果您仅比较1页PDF,则此building block是可选的。既然你谈到“建设计划”,情况可能就是这样。

    比较

    使用ImageMagick中的命令行实用程序为每个页面创建“diff”PDF页面:

    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的

    由于自动插入的元数据(例如当前日期+时间),PDF输出对于基于MD5hash的文件比较效果不佳。

    如果要自动发现diff PDF由纯白页组成的所有情况,您应该使用bmp256输出设备将PDF页面转换为无元数据的位图格式。你可以这样做:

    首先,找出PDF的页面大小格式。同样,这个小实用程序identify是任何ImageMagick安装的一部分:

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

    您可以将此值存储在如下环境变量中:

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

    现在Ghostscript发挥作用,使用一个命令行,其中包含上面发现的页面大小,因为它存储在变量中:

     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
    

    这为您提供了一个PPM(Portable PixMap),其分辨率为原始PDF页面的72 dpi。 72 dpi通常足以满足我们的需求...接下来,创建一个具有相同页面大小的纯白色PPM页面:

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

    -c "showpage"部分是一个PostScript命令,它告诉Ghostscript只发出一个空页面。

    MD5总和

    使用MD5哈希自动将原始PPM与白页PPM进行比较。如果它们相同,您可以节省地假设PDF之间没有差异,因此重命名或删除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
    

    这使您不必视觉检查没有任何差异的“差异PDF”。

答案 1 :(得分:24)

这是一个黑客攻击。

pdftotext file1.pdf
pdftotext file2.pdf
diff file1.txt file2.txt

答案 2 :(得分:5)

完成2行(全能)imagemagick和pdftk:

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

选项-verbose和-debug是可选的。

  • compare创建一个PDF,其中diff为红色像素。
  • pdftk将diff-pdf与背景PDF_1合并