PDF和图片的相互转换

文章目录

    • 用PyPDF2分割和合并PDF
      • 分割PDF
      • 合并PDF
    • 用wand.image将PDF转换为图片格式
    • 用fitz将图片转为PDF格式
      • 将PDF转为图片格式
      • 转为一张张PDF
      • 合为一个PDF
      • wake的使用

用PyPDF2分割和合并PDF

一篇好的博客链接:Python 深入浅出 - PyPDF2 处理 PDF 文件

"""
PyPDF2 中有两个最常用的类:PdfFileReader和PdfFileWriter,分别用于读取 PDF 和写入 PDF。
其中PdfFileReader传入参数可以是一个打开的文件对象,也可以是表示文件路径的字符串。
而PdfFileWriter则必须传入一个以写方式打开的文件对象。
"""

分割PDF

import sys
from PyPDF2 import PdfFileReader, PdfFileWriter
import os


# 读取的ptf文件路径
readFile = r'C:\Users\宋增\Desktop\yuyan\初阶\第9节-windows版本git的用法.pdf'
# 获取 PdfFileReader 对象
# 也可以写成 pdfFileReader = PdfFileReader(open(readFile, 'rb'))
pdfFileReader = PdfFileReader(readFile)

# getNumPages() 获取总页数
for page in range(pdfFileReader.getNumPages()):
    # 实例化对象
    pdfFileWriter = PdfFileWriter()
    # getPage(page) 从这个 PDF 文件中检索一个编号的页面
    # 根据每页返回的 PageObject,写入到文件
    pageObj = pdfFileReader.getPage(page)
    # addPage() 添加一个页面到这个PDF 文件,该页面通常从 PdfFileReader 实例获取
    # 将遍历的每一页添加到实例化对象中
    pdfFileWriter.addPage(pageObj)
    写入将ptf文件分割的每一张写入的文件路径
    writeFile = r'C:\Users\宋增\Desktop\python相关文件\存放分割PDF读取的图片'
    with open(writeFile + "\\" + '{}.pdf'.format(page), 'wb') as out:
        pdfFileWriter.write(out)

合并PDF

import sys
from PyPDF2 import PdfFileReader, PdfFileWriter
import os

# 实例化对象
pdfFileWriter = PdfFileWriter()
# 读取的ptf所有文件,列表
path = r'C:\Users\宋增\Desktop\yuyan\初阶'
readFiles = os.listdir(path)
writeFile = r'C:\Users\宋增\Desktop\python相关文件\存放合并PDF的文件'
# 第一个循环读取需要合并pdf文件
if not sys.warnoptions:
    import warnings
    warnings.simplefilter("ignore")
for file_nums in range(len(readFiles)):
    pdfFileReader = PdfFileReader(path + '//' + readFiles[file_nums])
    # 第二个循环遍历当前文件的每个pdf的每一页
    for page in range(pdfFileReader.getNumPages()):
        # 写入实例化对象中
        pdfFileWriter.addPage(pdfFileReader.getPage(page))
with open(writeFile + '\\' + '0.pdf', 'wb') as out:
    pdfFileWriter.write(out)

用wand.image将PDF转换为图片格式

官方文档:wand

  1. 要使用wand需要安装Ghostscript和ImageMagick
  2. 然后安装wand模块
from wand.image import Image
import cv2
import time
path = r'C:\Users\宋增\Desktop\yuyan\python\646633 PyQt5快速开发与实战电子书(1117).pdf'
savepath = r'C:\Users\宋增\Desktop\python相关文件\存放合并PDF的文件'
i = 0
name = 'A'
time_start1 = time.time()
with Image(filename=path) as img:
    image_page_num = len(img.sequence)
    print(time.time() - time_start1)
    time_start2 = time.time()
    with img.convert('pdf') as converted:
        print(time.time() - time_start2)
        converted.save(filename=os.path.join('%s/%s.pdf' % (savepath, name)))

用fitz将图片转为PDF格式

将PDF转为图片格式

import datetime
import os
import fitz  # fitz就是pip install PyMuPDF


def pyMuPDF_fitz(pdfPath, imagePath):
    startTime_pdf2img = datetime.datetime.now()  # 开始时间

    pdfDoc = fitz.open(pdfPath)  # 打开一个PDF文件,doc为Document类型,是一个包含每一页PDF文件的列表
    for pg in range(pdfDoc.pageCount):  # 遍历所有页面
        page = pdfDoc[pg]
        rotate = int(0)  # 页面旋转角度
        # 每个尺寸的缩放系数为1.3,这将为我们生成分辨率提高2.6的图像。
        # 此处若是不做设置,默认图片大小为:792X612, dpi=96
        # (dpi: 直接来说就是一英寸多少个像素点。常见取值 120,160,240。我一般称作像素密度,简称密度)
        # 设置图片相对于PDF文件在 X轴,Y轴 上的缩放比例
        zoom_x = 1.33333333  # (1.33333333-->1056x816)   (2-->1584x1224)
        zoom_y = 1.33333333
        mat = fitz.Matrix(zoom_x, zoom_y).preRotate(rotate)
        pix = page.getPixmap(matrix=mat, alpha=False)
        """
        - fitz.Matrix( 1, 1 )的两个参数表示宽度和高度的放大系数
        - fitz.Rect有好几种坐标模式,我选择了 (x0, y0, x1, y1 )这种坐标模式来定位要截取的区域
        - page.getPixmap传入放大系数和区域即可获取图片对象,可直接获取图片的数据也可以写入到文件保存起来
        -  以及定义其透明度的可选alpha字节描述
        - mat.preRotate (-90 )实现了截取区域逆时针旋转90度。
        - clip = fitz.Rect(x0, y0, x1, y1 )
        - pix = page.getPixmap(matrix=mat, alpha=False, clip=clip)
        """

        if not os.path.exists(imagePath):  # 判断存放图片的文件夹是否存在
            os.makedirs(imagePath)  # 若图片文件夹不存在就创建

        pix.writePNG(imagePath + '/' + 'images_%s.png' % pg)  # 将图片写入指定的文件夹内
        # pm.writeImage("%s%s.jpg" % (new_full_name, pg)) # 将其输入为相应的图片格式,可以为位图,也可以为矢量图
        # 本来想输出为jpg文件,但是在网页中都是png格式(即调用writePNG),再转换成别的图像文件前,最好查一下是否支持

    endTime_pdf2img = datetime.datetime.now()  # 结束时间
    print('pdf2img时间=', (endTime_pdf2img - startTime_pdf2img).seconds)


if __name__ == "__main__":
    path = r'C:\Users\宋增\Desktop\yuyan\python\OpenCV轻松入门:面向Python by 李立宗 (z-lib.org).pdf'
    savepath = r'C:\Users\宋增\Desktop\python相关文件\存放合并PDF的文件'
    pyMuPDF_fitz(path, savepath)

转为一张张PDF

# import glob
import os
import fitz

# 防止字符串乱码
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'

# 读取图片地址
img_path = r'C:\Users\宋增\Desktop\python相关文件\存放合并PDF的文件'
# 即将生成的pdf的目标地址
pdf_path = r'C:\Users\宋增\Desktop\python相关文件\存放分割PDF读取的图片'
# print(img_path + pdf_name + '.jpg')
# 使用glob读图:匹配所有的符合条件的文件,并将其以list的形式返回
# for img in sorted(glob.glob(img_path + pdf_name + '.jpg')):
for num, img in enumerate(os.listdir(img_path)):
    # 打开空文档
    doc = fitz.open()
    # 打开指定图片
    img_doc = fitz.open(os.path.join(img_path, img))
    # 使用图片创建单页的PDF
    pdf_bytes = img_doc.convertToPDF()
    img_pdf = fitz.open("pdf", pdf_bytes)
    # 将当前页写入文档
    doc.insertPDF(img_pdf)
    # 一直在保存为指定名称的PDF文件
    doc.save(pdf_path + '\\' + '{}.pdf'.format(num))
    # 关闭
    doc.close()

合为一个PDF

# 读取图片地址
img_path = r'C:\Users\宋增\Desktop\python相关文件\存放合并PDF的文件'
# 即将生成的pdf的目标地址
pdf_path = r'C:\Users\宋增\Desktop\python相关文件\存放分割PDF读取的图片'

# 循环path中的文件,可import os 然后用 for img in os.listdir(img_path)实现
# 这里为了让文件以1,2,3的形式进行拼接,就偷懒循环文件名中的数字。

# 打开空文档
doc = fitz.open()
for num, img in enumerate(os.listdir(img_path)):
    # 打开指定图片
    img_doc = fitz.open(os.path.join(img_path, img))
    pdf_bytes = img_doc.convertToPDF()
    # pdf_name = str(num) + '.pdf'
    img_pdf = fitz.open("pdf", pdf_bytes)
    doc.insertPDF(img_pdf)
doc.save(os.path.join(pdf_path, 'combined.pdf'))
doc.close()

wake的使用

# for root, dirs, files in os.walk(".", topdown=False):
#     for name in files:
#         print(os.path.join(root, name))
#     for name in dirs:
#         print(os.path.join(root, name))

你可能感兴趣的:(python,python)