将图像放在 PDF 上
Posted
技术标签:
【中文标题】将图像放在 PDF 上【英文标题】:Place image over PDF 【发布时间】:2011-02-24 21:52:56 【问题描述】:如何将图像放置在特定坐标位置的现有 PDF 文件上。 pdf 代表一页的图纸。图像将被缩放。我正在检查 ReportLab,但找不到答案。谢谢。
【问题讨论】:
图片总是出现在同一个位置吗? 是的,基本就是左下角附近的邮票。 下面的答案够吗?如果不是,那它有什么问题? 有没有办法在上面放一张图片(比如 png、jpg、gif)?在特定坐标?还是将 2 个 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,最简单的方法是:
-
将 pdf 转换为 .doc 或 .odt(检查 http://www.zamzar.com/)
根据需要将图像添加到转换后的文件中。
转换回 PDF(openoffice 和 libreoffice 可以轻松保存 pdf)
PS:如果pdf文件需要进一步编辑,请始终保留源.doc文件的备份,以便轻松进行更改,过多的转换会影响文件质量。
【讨论】:
以上是关于将图像放在 PDF 上的主要内容,如果未能解决你的问题,请参考以下文章
将反应项目部署到 github 页面面临公共文件夹中图像的问题
Android:给定原始图像的Uri,获取SD卡上图像的缩略图
使用 itextsharp 将图像 html 旁边的文本放置到 pdf