【问题标题】:Place image over PDF将图像放在 PDF 上
【发布时间】:2011-02-24 21:52:56
【问题描述】:

如何将图像放置在特定坐标位置的现有 PDF 文件上。 pdf 代表一页的图纸。图像将被缩放。我正在检查 ReportLab,但找不到答案。谢谢。

【问题讨论】:

  • 图片总是出现在同一个位置吗?
  • 是的,基本就是左下角附近的邮票。
  • 下面的答案够吗?如果不是,那它有什么问题?
  • 有没有办法在上面放一张图片(比如 png、jpg、gif)?在特定坐标?还是将 2 个 pdf 混合在一起的唯一解决方案?

标签: python pdf


【解决方案1】:

已经 5 年了,我认为这些答案需要一些 TLC。这是一个完整的解决方案。

以下是用 Python 2.7 测试的

安装依赖

pip install reportlab 
pip install pypdf2

施展魔法

from reportlab.pdfgen import canvas
from PyPDF2 import PdfFileWriter, PdfFileReader

# Create the watermark from an image
c = canvas.Canvas('watermark.pdf')

# Draw the image at x, y. I positioned the x,y to be where i like here
c.drawImage('test.png', 15, 720)

# Add some custom text for good measure
c.drawString(15, 720,"Hello World")
c.save()

# Get the watermark file you just created
watermark = PdfFileReader(open("watermark.pdf", "rb"))

# Get our files ready
output_file = PdfFileWriter()
input_file = PdfFileReader(open("test2.pdf", "rb"))

# Number of pages in input document
page_count = input_file.getNumPages()

# Go through all the input file pages to add a watermark to them
for page_number in range(page_count):
    print "Watermarking page {} of {}".format(page_number, page_count)
    # merge the watermark with the page
    input_page = input_file.getPage(page_number)
    input_page.mergePage(watermark.getPage(0))
    # add page from input file to output document
    output_file.addPage(input_page)

# finally, write "output" to document-output.pdf
with open("document-output.pdf", "wb") as outputStream:
    output_file.write(outputStream)

参考资料:

pypdf的新家: http://mstamy2.github.io/PyPDF2/

Reportlab 文档: http://www.reportlab.com/apis/reportlab/2.4/pdfgen.html

Reportlab 完整用户指南: https://www.reportlab.com/docs/reportlab-userguide.pdf

【讨论】:

  • 当您更新答案时,pdfrw 库也可以以非常相似的方式watermark,也可以采用另一种方式——允许您使用 pre-现有的 PDF 就好像它们是您 build with reportlab 的 PDF 中的图像(没有光栅化它们)。免责声明:我是pdfrw作者...
  • @PatrickMaupin 您可以使用 pdfrw 的现成答案吗?这将非常有用。
  • @PatrickMaupin pdfrw 可以从使用 png 或 jpeg 文件并在特定坐标处添加水印的水印示例中受益匪浅。目前可以吗?
【解决方案2】:

http://pybrary.net/pyPdf/:

from pyPdf import PdfFileWriter, PdfFileReader

output = PdfFileWriter()
input1 = PdfFileReader(file("document1.pdf", "rb"))
watermark = PdfFileReader(file("watermark.pdf", "rb"))

input1.mergePage(watermark.getPage(0))

# finally, write "output" to document-output.pdf
outputStream = file("document-output.pdf", "wb")
output.write(input1)
outputStream.close()

我认为它就像watermark,请参阅手册以获得更好的想法

【讨论】:

  • 感谢它运行良好,刚刚检查了文档中的 PdfFileReader.getPage() 和 PdfFileWriter.addPage() 方法。
  • 似乎 PyPdf 不再维护,宣布的延续站点也不再维护。从长远来看,还有什么其他解决方案?
  • page4 是从哪里来的?
  • @lalebarde: PyPDF2 是继任者。
【解决方案3】:

我结合了 ReportLab (http://www.reportlab.com/software/opensource/rl-toolkit/download/) 和 pyPDF (http://pybrary.net/pyPdf/) 直接插入图像而无需预先生成 PDF:

from pyPdf import PdfFileWriter, PdfFileReader
from reportlab.pdfgen import canvas
from StringIO import StringIO


# Using ReportLab to insert image into PDF
imgTemp = StringIO()
imgDoc = canvas.Canvas(imgTemp)

# Draw image on Canvas and save PDF in buffer
imgPath = "path/to/img.png"
imgDoc.drawImage(imgPath, 399, 760, 160, 160)    ## at (399,760) with size 160x160
imgDoc.save()

# Use PyPDF to merge the image-PDF into the template
page = PdfFileReader(file("document.pdf","rb")).getPage(0)
overlay = PdfFileReader(StringIO(imgTemp.getvalue())).getPage(0)
page.mergePage(overlay)

#Save the result
output = PdfFileWriter()
output.addPage(page)
output.write(file("output.pdf","w"))

【讨论】:

    【解决方案4】:

    感谢之前的答案。 python3.4 我的方式

    # -*- coding: utf-8 -*-
    from io import BytesIO
    from PyPDF2 import PdfFileWriter, PdfFileReader
    from reportlab.pdfgen import canvas
    from reportlab.lib.pagesizes import A4
    
    def gen_pdf():
        # there are 66 slides (1.jpg, 2.jpg, 3.jpg...)
        path = 'slades/{0}.jpg'
        pdf = PdfFileWriter()
    
        for num in range(1, 67):  # for each slide
            # Using ReportLab Canvas to insert image into PDF
            imgTemp = BytesIO()
            imgDoc = canvas.Canvas(imgTemp, pagesize=A4)
            # Draw image on Canvas and save PDF in buffer
            imgDoc.drawImage(path.format(num), -25, -45)
            # x, y - start position
            # in my case -25, -45 needed
            imgDoc.save()
            # Use PyPDF to merge the image-PDF into the template
            pdf.addPage(PdfFileReader(BytesIO(imgTemp.getvalue())).getPage(0))
    
        pdf.write(open("output.pdf","wb"))
    
    
    if __name__ == '__main__':
        gen_pdf()
    

    【讨论】:

      【解决方案5】:

      使用PyMuPDF 很容易做到这一点,无需合并两个 PDF:

      import fitz
      
      src_pdf_filename = 'source.pdf'
      dst_pdf_filename = 'destination.pdf'
      img_filename = 'barcode.jpg'
      
      # http://pymupdf.readthedocs.io/en/latest/rect/
      # Set position and size according to your needs
      img_rect = fitz.Rect(100, 100, 120, 120)
      
      document = fitz.open(src_pdf_filename)
      
      # We'll put image on first page only but you could put it elsewhere
      page = document[0]
      page.insertImage(img_rect, filename=img_filename)
      
      # See http://pymupdf.readthedocs.io/en/latest/document/#Document.save and
      # http://pymupdf.readthedocs.io/en/latest/document/#Document.saveIncr for
      # additional parameters, especially if you want to overwrite existing PDF
      # instead of writing new PDF
      document.save(dst_pdf_filename)
      
      document.close()
      

      【讨论】:

      • @j-owens - 我一直遇到 Rect 构造函数的问题。坐标好像不能正常工作,只能倒过来插入图片。
      • 原点 (0, 0) 从左上角开始,这与其他一些可能从左下角开始的库不同(尽管我遇到了一些来源奇怪的 PDF)。我想知道你的 y 坐标是否倒置了。
      • 我已经尝试过了,但它不起作用。任何想法为什么?看起来很整洁!
      【解决方案6】:

      这对我有用

      from PyPDF2 import PdfFileWriter, PdfFileReader
      
      def watermarks(temp, watermar,new_file):
          template = PdfFileReader(open(temp, 'rb'))
          wpdf = PdfFileReader(open(watermar, 'rb'))
          watermark = wpdf.getPage(0)
      
          for i in xrange(template.getNumPages()):
              page = template.getPage(i)
              page.mergePage(watermark)
              output.addPage(page)
      
              with open(new_file, 'wb') as f:
                  output.write(f)
      

      【讨论】:

        【解决方案7】:

        既然是现有的pdf,最简单的方法是:

        1. 将 pdf 转换为 .doc 或 .odt(检查 http://www.zamzar.com/
        2. 根据需要将图像添加到转换后的文件中。
        3. 转换回 PDF(openoffice 和 libreoffice 可以轻松保存 pdf)

        PS:如果pdf文件需要进一步编辑,请始终保留源.doc文件的备份,以便轻松进行更改,过多的转换会影响文件质量。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-05-16
          • 1970-01-01
          • 1970-01-01
          • 2014-07-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-25
          相关资源
          最近更新 更多