【问题标题】:Cropping pages of a .pdf file裁剪 .pdf 文件的页面
【发布时间】:2010-10-02 05:09:24
【问题描述】:

我想知道是否有人有任何以编程方式处理 .pdf 文件的经验。我有一个 .pdf 文件,我需要将每一页裁剪成一定大小。

在谷歌快速搜索后,我找到了 python 的 pyPdf 库,但我的实验失败了。当我更改页面对象上的cropBox 和 trimBox 属性时,结果不是我所期望的,而且看起来很随机。

有人有这方面的经验吗?代码示例将不胜感激,最好是在 python 中。

【问题讨论】:

  • 很好的问题,但有点惊讶它还没有因为太宽泛而被关闭。

标签: python pdf pypdf


【解决方案1】:

您可能正在寻找免费的解决方案,但如果您有钱可以花钱,PDFlib 是一个很棒的图书馆。它从来没有让我失望过。

【讨论】:

    【解决方案2】:

    您可以将 PDF 转换为 Postscript(pstopdf 或 ps2pdf),然后对 Postscript 文件进行文本处理。之后,您可以将输出转换回 PDF。

    如果您要处理的 PDF 都由同一个应用程序生成并且有些相似,这将非常有效。如果它们来自不同的来源,通常很难处理 Postscript 文件 - 结构变化很大。但是,即使您可以使用一些正则表达式来修复页面大小等。

    【讨论】:

      【解决方案3】:

      Acrobat Javascript API 有一个 setPageBoxes 方法,但 Adob​​e 不提供任何 Python 代码示例。仅限 C++、C# 和 VB。

      【讨论】:

        【解决方案4】:

        pyPdf 在这方面符合我的期望。使用以下脚本:

        #!/usr/bin/python
        #
        
        from pyPdf import PdfFileWriter, PdfFileReader
        
        with open("in.pdf", "rb") as in_f:
            input1 = PdfFileReader(in_f)
            output = PdfFileWriter()
        
            numPages = input1.getNumPages()
            print "document has %s pages." % numPages
        
            for i in range(numPages):
                page = input1.getPage(i)
                print page.mediaBox.getUpperRight_x(), page.mediaBox.getUpperRight_y()
                page.trimBox.lowerLeft = (25, 25)
                page.trimBox.upperRight = (225, 225)
                page.cropBox.lowerLeft = (50, 50)
                page.cropBox.upperRight = (200, 200)
                output.addPage(page)
        
            with open("out.pdf", "wb") as out_f:
                output.write(out_f)
        

        生成的文档有一个 200x200 点的裁切框,从媒体框内的 25,25 点开始。 裁剪框在裁切框内 25 磅。

        以下是我的示例文档在使用上述代码处理后在 acrobat Professional 中的外观:

        此文档在 acrobat reader 中加载时将显示为空白。

        【讨论】:

        • 这段代码和我试验的代码效果一样;结果文档的页面当然被裁剪了,但都是空白的。任何想法为什么会这样?
        • 为什么原始页面文本(在修剪框之外)“跟随”裁剪的 PDF?如果我执行上述操作并尝试将裁剪包含在另一个 PDF 中(例如,通过 LaTex)并缩小裁剪,原始文本仍然存在,可选择,尽管不可见。修改page.mediaBox 似乎没有帮助。关于如何实际将 PDF 缩减为 trimBox 大小的任何建议?谢谢。
        • @danio 没问题。我所追求的是对 PDF 区域和文本的破坏性裁剪。最后,我设法用ghostscript 轻松做到了。
        • 另一个可能导致空白页的罪魁祸首(问我怎么知道...),至少如果一个人使用较新的(API 兼容)PyPDF2,是关闭支持PdfFileReader 的输入文件在PdfFileWriter 上调用write() 之前;这些页面似乎没有缓存到内存中,而是根据需要从磁盘读取(这很聪明),因此如果您在写入输出文件之前关闭输入文件,它将找不到内容 - 而不是报告一个错误,它会默默地创建空白页面(这似乎不太聪明)。
        • @JackDaniels 这是很久以前的事了:首先像上面解释的那样进行调整大小裁剪。然后像gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=destructive_crop.pdf resize_crop.pdf
        【解决方案5】:

        用这个来获取pdf的维度

        from PyPDF2 import PdfFileWriter,PdfFileReader,PdfFileMerger
        
        pdf_file = PdfFileReader(open("/Users/user.name/Downloads/sample.pdf","rb"))
        page = pdf_file.getPage(0)
        print(page.cropBox.getLowerLeft())
        print(page.cropBox.getLowerRight())
        print(page.cropBox.getUpperLeft())
        print(page.cropBox.getUpperRight())
        

        在此之后获取页面参考,然后应用裁剪命令

        page.mediaBox.lowerRight = (lower_right_new_x_coordinate, lower_right_new_y_coordinate)
        page.mediaBox.lowerLeft = (lower_left_new_x_coordinate, lower_left_new_y_coordinate)
        page.mediaBox.upperRight = (upper_right_new_x_coordinate, upper_right_new_y_coordinate)
        page.mediaBox.upperLeft = (upper_left_new_x_coordinate, upper_left_new_y_coordinate)
        
        #for example :- my custom coordinates 
        #page.mediaBox.lowerRight = (611, 500)
        #page.mediaBox.lowerLeft = (0, 500)
        #page.mediaBox.upperRight = (611, 700)
        #page.mediaBox.upperLeft = (0, 700)
        

        【讨论】:

        • 非常感谢。如何应用自定义坐标?我的意思是我怎样才能定义合适的坐标?
        • @YasserKhalil 您可以通过试错法或根据您的用例找出答案。
        • @YasserKhalil 请参考我的回答。
        【解决方案6】:

        我如何知道要裁剪的坐标?

        感谢以上所有回答。

        步骤 1. 运行以下代码得到 (x1, y1)。

        from PyPDF2 import PdfFileWriter, PdfFileReader
        
        input = PdfFileReader(open("test.pdf","rb"))
        page = input.getPage(0)
        print(page.cropBox.getUpperRight())
        

        第 2 步。以全屏模式查看 pdf 文件。

        步骤 3. 将屏幕捕获为图像文件 screen.jpg。

        步骤 4. 通过 M$ paint 或 GIMP 打开 screen.jpg。这些应用程序显示光标的坐标。

        步骤 5. 记住以下坐标,(x2, y2), (x3, y3), (x4, y4) 和 (x5, y5),其中 (x4, y4) 和 (x5, y5) 确定矩形你想裁剪。

        Step 6. 通过以下公式获取 page.cropBox.upperLeft 和 page.cropBox.lowerRight。这是一个tool 用于计算。

        page.cropBox.upperLeft = (x1*(x4-x2)/(x3-x2),(1-y4/y3)*y1)
        page.cropBox.lowerRight = (x1*(x5-x2)/(x3-x2),(1-y5/y3)*y1)
        

        第 7 步。运行以下代码以裁剪 pdf 文件。

        from PyPDF2 import PdfFileWriter, PdfFileReader
        
        output = PdfFileWriter() 
        input = PdfFileReader(open('test.pdf', 'rb')) 
        
        n = input.getNumPages()
        
        for i in range(n):
          page = input.getPage(i)
          page.cropBox.upperLeft = (100,200)
          page.cropBox.lowerRight = (300,400)
          output.addPage(page) 
          
        outputStream = open('result.pdf','wb') 
        output.write(outputStream) 
        outputStream.close() 
        

        【讨论】:

          【解决方案7】:

          裁剪 .pdf 文件的页面

          from PIL import Image
          def ImageCrop():
              img = Image.open("page_1.jpg")
              left = 90
              top = 580
              right = 1600
              bottom = 2000
              img_res = img.crop((left, top, right, bottom))
              with open(outfile4, 'w') as f:
                  img_res.save(outfile4,'JPEG')
          ImageCrop()
          

          【讨论】:

            猜你喜欢
            • 2011-03-23
            • 2014-12-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-12-23
            • 2015-05-29
            • 1970-01-01
            相关资源
            最近更新 更多