sakura32 发表于 2024-3-30 15:24

PDF⇋图片转换,PDF合并分割

最近工作的时候一直有PDF转图片和分割、图片转PDF的需求,用adobe和wps把图片转成pdf时图片会变糊,于是摸鱼的时候做了两个小工具。
为了方便使用,没有做gui,只能拖入文件到程序上或者命令行使用
基本上抄的pymupdf官方的用法,没有做任何报错的处理,用来合并电子发票的PDF时会报错,这种情况我一般用另一个工具都转成图片后再用图片合并PDF解决,所以懒得改了

1.图片和PDF相互转换
把文件/文件夹拖到程序上,如果拖入的是图片则合并成1个PDF,如果是PDF则导出为图片,如果既有图片又有PDF则不做处理

2.PDF合并和切割
把文件/文件夹拖到程序上,如果拖入的是单个PDF则切割,如果是多个PDF则合并

下载地址:
https://wwz.lanzout.com/b01g9e7yh
密码:1234

源码地址:
https://521github.com/PPJUST/simple-tools/blob/main/PDF%26%E5%9B%BE%E7%89%87%E4%BA%92%E8%BD%AC.py
https://521github.com/PPJUST/simple-tools/blob/main/PDF%E6%8B%86%E5%88%86%26%E5%90%88%E5%B9%B6.py
1.
"""
更新日期:
2024.03.27

功能:
PDF导出为图片,图片合并为一个PDF
"""
import os
import sys
import tkinter.messagebox

import filetype
import fitz

try:
    drop_paths = sys.argv
except IndexError:
    drop_paths = []


def pdf_to_image(pdf_path: str):
    """将pdf每页导出为图片"""
    doc = fitz.open(pdf_path)
    # 根据页数分别处理,如果是单页则直接导出图片,如果为多页则导出到一个文件夹中
    pages_count = doc.page_count
    filetitle = os.path.basename(os.path.splitext(pdf_path))
    dirpath = os.path.dirname(pdf_path)
    if pages_count == 1:
      pix = doc.get_pixmap(dpi=300)
      # 使用官方的pix.save方法保存图片
      pix.save(f'{dirpath}/{filetitle}.png')
      # 使用PIL库保存图片
      # image = Image.frombytes("RGB", (pix.width, pix.height), pix.samples)
      # image.save(f'{dirpath}/{filetitle}.png')
    elif pages_count > 1:
      os.mkdir(f'{dirpath}/{filetitle}')
      for index, page in enumerate(doc, start=1):
            pix = page.get_pixmap(dpi=300)
            # 使用官方的pix.save方法保存图片
            pix.save(f'{dirpath}/{filetitle}/{index}.png')
            # 使用PIL库保存图片
            # image = Image.frombytes("RGB", (pix.width, pix.height), pix.samples)
            # image.save(f'{dirpath}/{filetitle}/{index}.png')


def image_to_pdf(images: list, output: str = 'output.pdf'):
    """将图片合并为pdf"""
    merged_pdf = fitz.open()# 最终合并的PDF

    for image_file in images:
      # 读取图片,转为PDF流
      img = fitz.open(image_file)
      # rect = img.rect# 读取图片尺寸
      pdf_bytes = img.convert_to_pdf()
      img.close()
      # 读取PDF流,转为PDF对象
      img_page = fitz.open("pdf", pdf_bytes)
      # 插入
      merged_pdf.insert_pdf(img_page)

    dirpath = os.path.dirname(images)
    merged_pdf.save(f'{dirpath}/{output}')
    merged_pdf.close()


def is_image(file: str):
    """文件是否是图片"""
    return filetype.is_image(file)


def is_pdf(file: str):
    """文件是否是pdf"""
    kind = filetype.guess(file)
    if kind is None:
      return False

    guess_type = kind.extension
    if guess_type == 'pdf':
      return True
    else:
      return False


def get_files(folder: str):
    """获取文件夹下所有文件路径"""
    files = []
    for dirpath, dirnames, filenames in os.walk(folder):
      for j in filenames:
            filepath_join = os.path.normpath(os.path.join(dirpath, j))
            files.append(filepath_join)

    return files


def show_info():
    tkinter.Tk().withdraw()
    tkinter.messagebox.showinfo(title='使用说明',
                              message='直接将文件/文件夹拖到程序上使用。\n拖入图片:合并为1个PDF\n拖入PDF:导出每页为图片')


def main():
    # 收集全部文件
    files = []
    for path in drop_paths:
      if os.path.isfile(path):
            files.append(path)
      else:
            walks = get_files(path)
            files += walks

    # 按文件类型分类
    images =
    pdfs =

    # 如果同时存在图片和pdf,则不做处理直接退出
    if images and pdfs:
      return

    if images:# 图片转pdf
      image_to_pdf(images)
    elif pdfs:# pdf导出图片
      for pdf in pdfs:
            pdf_to_image(pdf)


if __name__ == '__main__':
    if drop_paths:
      main()
    else:
      show_info()
2.
import os
import sys
import tkinter.messagebox

import filetype
import fitz

try:
    drop_paths = sys.argv
except IndexError:
    drop_paths = []


def merge_pdfs(pdfs_path: list, output: str = 'output.pdf'):
    """合并多个PDF"""
    merged_pdf = fitz.open()# 最终合并的PDF

    for child_pdf in pdfs_path:
      pdf = fitz.open(child_pdf)
      for page_num in range(pdf.page_count):
            merged_pdf.insert_pdf(pdf, from_page=page_num, to_page=page_num, start_at=merged_pdf.page_count)
      pdf.close()

    dirpath = os.path.dirname(pdfs_path)
    merged_pdf.save(f'{dirpath}/{output}')
    merged_pdf.close()


def split_pdf(pdf_path: str):
    """拆分PDF的每页为单独的PDF"""
    source_pdf = fitz.open(pdf_path)

    page_count = source_pdf.page_count
    if page_count == 1:
      return
    elif page_count > 1:
      filetitle = os.path.basename(os.path.splitext(pdf_path))
      dirpath = os.path.dirname(pdf_path)
      os.mkdir(f'{dirpath}/{filetitle}')
      for page_num in range(source_pdf.page_count):
            single_pdf = fitz.open()
            single_pdf.insert_pdf(source_pdf, from_page=page_num, to_page=page_num)
            single_pdf.save(f'{dirpath}/{filetitle}/{page_num + 1}.pdf')
            single_pdf.close()

    source_pdf.close()


def get_files(folder: str):
    """获取文件夹下所有文件路径"""
    files = []
    for dirpath, dirnames, filenames in os.walk(folder):
      for j in filenames:
            filepath_join = os.path.normpath(os.path.join(dirpath, j))
            files.append(filepath_join)

    return files


def is_pdf(file: str):
    """文件是否是pdf"""
    kind = filetype.guess(file)
    if kind is None:
      return False

    guess_type = kind.extension
    if guess_type == 'pdf':
      return True
    else:
      return False


def show_info():
    tkinter.Tk().withdraw()
    tkinter.messagebox.showinfo(title='使用说明',
                              message='直接将文件/文件夹拖到程序上使用。\n拖入多个PDF:合并为1个PDF\n拖入单个PDF:拆分每页为单独的PDF')


def main():
    # 收集全部文件
    files = []
    for path in drop_paths:
      if os.path.isfile(path):
            files.append(path)
      else:
            walks = get_files(path)
            files += walks

    # 按文件类型分类
    pdfs =

    if len(pdfs) == 1:# 拆分PDF
      split_pdf(pdfs)
    elif len(pdfs) > 1:# 合并PDF
      merge_pdfs(pdfs)


if __name__ == '__main__':
    if drop_paths:
      main()
    else:
      show_info()

haoyou11 发表于 2024-3-30 16:55

好东西要支持。

roothalo 发表于 2024-3-30 16:56

支持一下

MaGizzZ 发表于 2024-3-31 17:45



报错!!

sellcheapest 发表于 2024-4-6 03:09

好东西,不错不错

xajjunjun 发表于 2024-7-16 10:34

支持一下
页: [1]
查看完整版本: PDF⇋图片转换,PDF合并分割