吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1790|回复: 6
收起左侧

[Python 原创] PDF⇋图片转换,PDF合并分割

[复制链接]
sakura32 发表于 2024-3-30 15:24
最近工作的时候一直有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.
[Python] 纯文本查看 复制代码
"""
更新日期:
2024.03.27

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

import filetype
import fitz

try:
    drop_paths = sys.argv[1:]
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)[0])
    dirpath = os.path.dirname(pdf_path)
    if pages_count == 1:
        pix = doc[0].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[0].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[0])
    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 = [i for i in files if is_image(i)]
    pdfs = [i for i in files if is_pdf(i)]

    # 如果同时存在图片和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.
[Python] 纯文本查看 复制代码
import os
import sys
import tkinter.messagebox

import filetype
import fitz

try:
    drop_paths = sys.argv[1:]
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[0])
    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)[0])
        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 = [i for i in files if is_pdf(i)]

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


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

免费评分

参与人数 4吾爱币 +9 热心值 +4 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
xlln + 1 + 1 我很赞同!
yanglinman + 1 谢谢@Thanks!
chen1987 + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

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
支持一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-15 11:24

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表