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拼接发效果

2. 当 left和buttom都不为0,即RectangleObject([91.841, 38.5506, 261.791, 95.1271])
用上面方法拼接出来的效果, 

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

相关推荐

最近更新

  1. 基于Gunicorn+Flask+Docker模型高并发部署

    2024-01-05 18:14:02       0 阅读
  2. SQL FOREIGN KEY

    2024-01-05 18:14:02       0 阅读
  3. 安全保障措施

    2024-01-05 18:14:02       0 阅读
  4. Android IdleHandler源码分析

    2024-01-05 18:14:02       1 阅读
  5. docker-1

    docker-1

    2024-01-05 18:14:02      1 阅读
  6. Git批量删除本地h和远程分支说明

    2024-01-05 18:14:02       1 阅读
  7. mvccaa

    2024-01-05 18:14:02       1 阅读
  8. Linux 常用指令详解

    2024-01-05 18:14:02       1 阅读
  9. 第2章 源码编译构建LAMP

    2024-01-05 18:14:02       1 阅读

热门阅读

  1. centos6后台启动docker

    2024-01-05 18:14:02       33 阅读
  2. 2401vim,vim重要修改更新大全

    2024-01-05 18:14:02       26 阅读
  3. 用RC2CryptoServiceProvider来加密解密

    2024-01-05 18:14:02       45 阅读
  4. 常用材料五行数据库超全汇总

    2024-01-05 18:14:02       31 阅读
  5. 【LeetCode】1321. 餐馆营业额变化增长

    2024-01-05 18:14:02       35 阅读
  6. http请求转发、springboot请求转发、servlet转发请求

    2024-01-05 18:14:02       41 阅读
  7. python实现selenium的所有方法

    2024-01-05 18:14:02       31 阅读
  8. 【PHP】获取 URL 中域名后的路径

    2024-01-05 18:14:02       34 阅读