pypdf 将 PDF两个页面拼接成一个页面进一步详解

pypdf 原库名Pypdf2(已弃用,文档PyPDF2 RectangleObject类_w3cschool)

pypdf 官方文档 The Transformation Class --- pypdf 3.17.4 documentation

pypdf 将两个PDF页面在x轴,y轴进行平移调整位置之后,直接用merge_page拼接在一起,或者PageObject.create_blank_page 先创建一个空白页面,再将两个页面添加到空白页面上,

参考的文章Alternative to add_transformation translate · Issue #1426 · py-pdf/pypdf · GitHub

page1.merge_page(page2, expand=True) doesn't seem to work · Issue #1035 · py-pdf/pypdf · GitHub

prpdf github中的问题解决页面拼接, 问题页面 https://github.com/py-pdf/pypdf/issues?page=2&q=is%3Aissue+is%3Aopen

小日子的两个案例,拼接在右侧

Pythonで2ページのPDFを見開き1ページに結合する方法 - ガンマソフト

Cropping and Transforming PDFs --- PyPDF2 documentation

其他的案例

Blank pages in output file using PyPDF2 in Python ... - Alteryx Community

https://www.coder.rs/d/247-pythongei-pdfde-zhi-ding-ye-tian-jia-tu-pian-dao-zhi-ding-wei-zhi

多种方式实现PDF合并、生成目录及大纲、添加水印 - 徐彪的网络日志

复制代码
1. 拼接的两个PDF都是正常的,距离左侧和底部都是0
  拼接过程中真正起作用的是page.mediabox和page.cropbox
from pypdf import PdfWriter, PdfReader, PageObject, Transformation
from pypdf.generic import RectangleObject
def merge():
    file_path1 = r"1703906324193.pdf"
    file_path2 = r"1703906324193.pdf"
    
    reader = PdfReader(file_path1)
    page1 = reader.pages[0]
    print(page1.mediabox)
    print(page1.trimbox)
    print(page1.cropbox)
    print(page1.bleedbox)
    print(page1.artbox)
    # 0.0, 0.0, 120.16, 159.92 对应 left, bottom, right, top
    # page1.mediabox: RectangleObject([0.0, 0.0, 120.16, 159.92])

    reader2 = PdfReader(file_path2)
    page2 = reader2.pages[0]

    height = page1.cropbox.height
    print('height:', height)
    # x轴不动,沿y轴向上平移page1的高度,将page1在下方,page2在上方(tx,ty可为负值)
    op = Transformation().translate(tx=0, ty=height)
    page2.add_transformation(op)
    cb = page2.cropbox
    # page2向y轴正向平移后bottom和top 加上平移的高度
    page2.mediabox = RectangleObject((cb.left, cb.bottom + height, cb.right, cb.top + height))
    page2.cropbox = RectangleObject((cb.left, cb.bottom + height, cb.right, cb.top + height))
    # page2.trimbox = RectangleObject((cb.left, cb.bottom + height, cb.right, cb.top + height))
    # page2.bleedbox = RectangleObject((cb.left, cb.bottom + height, cb.right, cb.top + height))
    # page2.artbox = RectangleObject((cb.left, cb.bottom + height, cb.right, cb.top + height))
    print('page2.mediabox:', page2.mediabox)
    # page1合并page2
    page1.merge_page(page2, expand=True)
    mb = page1.mediabox
    print('mb:', mb)
    print(mb.bottom)
    print(cb.bottom)
    # page1 在bottom 或者 top上 加 page2的高度,
    page1.mediabox = RectangleObject((mb.left, mb.bottom + cb.top, mb.right, mb.top))
    page1.cropbox = RectangleObject((mb.left, mb.bottom + cb.top, mb.right, mb.top))
    # page1.cropbox = RectangleObject((mb.left, mb.bottom, mb.right, mb.top + cb.top))
    # page1.trimbox = RectangleObject((mb.left, mb.bottom + cb.bottom, mb.right, mb.top))
    # page1.bleedbox = RectangleObject((mb.left, mb.bottom + cb.bottom, mb.right, mb.top))
    # page1.artbox = RectangleObject((mb.left, mb.bottom + cb.bottom, mb.right, mb.top))
    print('page1.mediabox:', page1.mediabox)
    
    writer = PdfWriter()
    writer.add_page(page1)
    with open("output96.pdf", "wb") as fp:
        writer.write(fp)
2. 当 left和buttom都不为0,即RectangleObject([91.841, 38.5506, 261.791, 95.1271])
用上面方法拼接出来的效果

def merge():
    file_path1 = "1.pdf"
    file_path2 = "2.pdf"
    
    outfile = './output96.pdf'
    reader3 = PdfReader(file_path1)
    # 对p1的每页都拼接 p2, p1在上方, p2在下方
    writers = PdfWriter()
    for i in range(len(reader3.pages)):
        p1 = reader3.pages[i] #p1.cropbox RectangleObject([91.841, 38.5506, 261.791, 95.1271])
        
        reader = PdfReader(file_path2)
        p2 = reader.pages[0] #p2.cropbox= RectangleObject([91.841, 38.5506, 261.791, 95.1271])
        
        p1_left = p1.cropbox.left
        p1_bottom = p1.cropbox.bottom
        p3_right = p1.cropbox.right
        tem = p2.cropbox.top - p2.cropbox.bottom
        # p1 向左和向上平移
        op1 = Transformation().translate(tx=-p1.cropbox.left, ty=(p2.cropbox.top - p2.cropbox.bottom)-p1_bottom)
        p1.add_transformation(op1)
        
        # p2 向左和向下, tx为正数向右平移
        op2 = Transformation().translate(tx=-p2.cropbox.left, ty=-p2.cropbox.bottom)
        p2.add_transformation(op2)

        p2.cropbox = RectangleObject((0, 0, p2.cropbox.right, p2.cropbox.top))
        p2.trimbox = RectangleObject((0, 0, p2.mediabox.right, p2.mediabox.top))
        p2.bleedbox = RectangleObject((0, 0, p2.mediabox.right, p2.mediabox.top))
        p2.artbox = RectangleObject((0, 0, p2.mediabox.right, p2.mediabox.top))
        
        p1.merge_page(p2, expand=True)
        mb = p1.mediabox
        cb = p2.cropbox
        p1.mediabox = RectangleObject((mb.left, mb.bottom + cb.bottom, p3_right, p1.cropbox.top + tem))
        p1.cropbox = RectangleObject((mb.left, mb.bottom + cb.bottom, p3_right-p1_left, p1.cropbox.top + tem-p1_bottom))
        p1.trimbox = RectangleObject((mb.left, mb.bottom + cb.bottom, p3_right, p1.cropbox.top))
        p1.bleedbox = RectangleObject((mb.left, mb.bottom + cb.bottom, p3_right, p1.cropbox.top))
        p1.artbox = RectangleObject((mb.left, mb.bottom + cb.bottom, p3_right, p1.cropbox.top))
        writers.add_page(p1)
    with open(outfile, mode='wb') as f:
        writers.write(f)
  1. left 和buttom 都为0时用方法1拼接发效果
  1. 当 left和buttom都不为0,即RectangleObject([91.841, 38.5506, 261.791, 95.1271])

用上面方法拼接出来的效果,

方法2调整之后的效果 和left 和buttom 都为0时用方法1拼接发效果一样

相关推荐
拓端研究室6 小时前
专题:2025人形机器人、工业机器人、智能焊接机器人、扫地机器人产业洞察报告 | 附158+份报告PDF、数据仪表盘汇总下载
microsoft·机器人·pdf
TextIn智能文档云平台8 小时前
复杂PDF文档结构化提取全攻略——从OCR到大模型知识库构建
pdf·ocr
会飞的小菠菜8 小时前
PDF文件中的广告二维码图片该怎么批量删除
pdf·删除·二维码·批量
一只花里胡哨的程序猿1 天前
odoo打印pdf速度慢问题
pdf·odoo
灵海之森1 天前
Python将md转html,转pdf
pdf
阿幸软件杂货间1 天前
最新PDF版本!Acrobat Pro DC 2025,解压即用版
pdf·adobe acrobat·acrobat
星空的资源小屋1 天前
网易UU远程,免费电脑远程控制软件
人工智能·python·pdf·电脑
会飞的小菠菜1 天前
如何一次性将多个PPT幻灯片批量转换成PDF文档
pdf·powerpoint·ppt·批量·格式转换
somethingGoWay2 天前
wpf .netcore 导出pdf文件
pdf·wpf·.netcore
小白电脑技术2 天前
PDF教程|如何把想要的网页保存下来?
pdf·电脑