Python自制一个PDF转PNG图片小工具

 更新时间:2023年02月19日 08:47:48   作者:Sir 老王  
这篇文章主要为大家详细介绍了如何利用Python中的PyQt5自制一个PDF转PNG格式图片的小工具,文中的示例代码讲解详细,感兴趣的可以了解一下

使用PyQt5应用程序制作PDF转换成图片的小工具,可以导入PDF文档后一键生成对应的PNG图片。

PDF图片转换小工具使用的中间件:

  • python版本:3.6.8
  • UI应用版本:PyQt5
  • PDF文件操作非标准库:PyPDF2
  • PNG图片生成库:PyMuPDF
pip install PyQt5

pip install PyPDF2

pip install PyMuPDF==1.18.17

将需要使用到的python标准库或非标准库全部导入到我们的代码块中进入开发环节。

# Importing all the classes from the PyQt5.QtGui module.
from PyQt5.QtGui import *

# Importing all the classes from the PyQt5.QtCore module.
from PyQt5.QtCore import *

# Importing all the classes from the PyQt5.QtWidgets module.
from PyQt5.QtWidgets import *

# Importing the `fitz` module.
import fitz

# Importing the PyPDF2 module.
import PyPDF2

# Importing the `sys` module.
import sys

# Importing the os module.
import os

# Importing the traceback module.
import traceback

接下来直接进入正题,首先创建名称为PdfToPngUI的python类,将UI组件及布局和相关的槽函数都写入到这个类中。

# This class is a widget that contains a button and a text box. When the button is clicked, the text box is populated with
# the path to the converted file
class PdfToPngUI(QWidget):
    def __init__(self):
        """
        A constructor. It is called when an object is created from a class and it allows the class to initialize the
        attributes of a class.
        """
        super(PdfToPngUI, self).__init__()
        self.init_ui()

    def init_ui(self):
        """
        This function initializes the UI.
        """
        self.setWindowTitle('PDF图片转换工具 公众号:Python 集中营')
        self.setWindowIcon(QIcon('analysis.ico'))
        self.resize(600, 400)

        self.source_pdf_path = QLineEdit()
        self.source_pdf_path.setPlaceholderText('PDF文件路径')
        self.source_pdf_path.setReadOnly(True)

        self.source_pdf_btn = QPushButton()
        self.source_pdf_btn.setText('导入')
        self.source_pdf_btn.clicked.connect(self.source_pdf_btn_click)

        self.target_png_path = QLineEdit()
        self.target_png_path.setPlaceholderText('目标图片存储路径')
        self.target_png_path.setReadOnly(True)

        self.target_png_btn = QPushButton()
        self.target_png_btn.setText('路径')
        self.target_png_btn.clicked.connect(self.target_png_btn_click)

        self.start_btn = QPushButton()
        self.start_btn.setText('PDF一键生成PNG图片')
        self.start_btn.clicked.connect(self.start_btn_click)

        self.brower = QTextBrowser()
        self.brower.setReadOnly(True)
        self.brower.setFont(QFont('宋体', 8))
        self.brower.setPlaceholderText('日志处理过程区域...')
        self.brower.ensureCursorVisible()

        grid = QGridLayout()
        grid.addWidget(self.source_pdf_path, 0, 0, 1, 2)
        grid.addWidget(self.source_pdf_btn, 0, 2, 1, 1)
        grid.addWidget(self.target_png_path, 1, 0, 1, 2)
        grid.addWidget(self.target_png_btn, 1, 2, 1, 1)
        grid.addWidget(self.start_btn, 2, 0, 1, 3)
        grid.addWidget(self.brower, 3, 0, 1, 3)

        self.pdf_thread = WorkThread(self)
        self.pdf_thread.message.connect(self.show_message)
        self.pdf_thread.finished.connect(self.finished)

        self.setLayout(grid)

    def show_message(self, text):
        """
        It shows a message

        :param text: The text to be displayed
        """
        cursor = self.brower.textCursor()
        cursor.movePosition(QTextCursor.End)
        self.brower.append(text)
        self.brower.setTextCursor(cursor)
        self.brower.ensureCursorVisible()

    def source_pdf_btn_click(self):
        """
        It opens a file dialog box to select the source PDF file.
        """
        source_pdf_path = QFileDialog.getOpenFileName(self, "选取文件", os.getcwd(), "PDF File (*.pdf)")
        self.source_pdf_path.setText(source_pdf_path[0])

    def target_png_btn_click(self):
        """
        A function that is called when the target_png_btn is clicked.
        """
        target_png_path = QFileDialog.getExistingDirectory(self, '选择文件夹', os.getcwd())
        self.target_png_path.setText(target_png_path)

    def start_btn_click(self):
        """
        A function that is called when the start button is clicked.
        """
        self.pdf_thread.start()
        self.start_btn.setEnabled(False)

    def finished(self, finished):
        """
        A function that is called when the target_png_btn is clicked
        """
        if finished is True:
            self.start_btn.setEnabled(True)

通过上面的PdfToPngUI类处理,这个时候UI组件及布局和槽函数已经开发完成了,应用的页面效果如下。

然后,我们开始业务逻辑的开发。这里将业务逻辑使用单独的子线程开发避免和页面的主线程发生阻塞。

创建一个子线程的python类WorkThread并继承自QThread子线程,将PDF图片转换的过程写到里面。

# It's a QThread that runs a function in a separate thread
class WorkThread(QThread):
    message = pyqtSignal(str)
    finished = pyqtSignal(bool)

    def __init__(self, parent=None):
        """
        A constructor that initializes the class.

        :param parent: The parent widget
        """
        super(WorkThread, self).__init__(parent)
        self.working = True
        self.parent = parent

    def __del__(self):
        """
        A destructor. It is called when the object is destroyed.
        """
        self.working = False

    def run(self):
        """
        PDF转换图片的业务函数。
        """
        try:
            source_pdf_path = self.parent.source_pdf_path.text().strip()
            target_png_path = self.parent.target_png_path.text().strip()
            if source_pdf_path == '' or target_png_path == '':
                self.message.emit('来源文件路径或目标存储路径不能为空!')
                self.finished.emit(True)
                return

            self.message.emit('源文件路径:{}'.format(source_pdf_path))
            self.message.emit('目标文件路径:{}'.format(target_png_path))

            pdf_ = fitz.open(source_pdf_path)
            self.message.emit('成功打开PDF文件对象!')
            reader = PyPDF2.PdfFileReader(source_pdf_path)
            self.message.emit('PDF文件流处理完成!')
            page_num = reader.getNumPages()
            self.message.emit('PDF文件页数读取完成!')

            for n in range(0, page_num):
                page = pdf_.load_page(n)
                pix_ = page.get_pixmap()
                pix_.save(os.path.join(target_png_path, str(n) + '.png'))
                self.message.emit('图片保存成功:{}'.format(os.path.join(target_png_path, str(n) + '.png')))
            self.message.emit('PNG图片全部转换完成!')
            self.finished.emit(True)
        except:
            traceback.print_exc()
            self.message.emit('程序运行出现错误,请检查参数是否设置正确!')
            self.finished.emit(True)

经过上述的UI界面组件以及业务线程的开发,功能已经实现了,下面使用main函数调起整个应用就OK了。

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = PdfToPngUI()
    main.show()
    sys.exit(app.exec_())

以上就是Python自制一个PDF转PNG图片小工具的详细内容,更多关于Python PDF转PNG的资料请关注脚本之家其它相关文章!

相关文章

  • python 巧用正则寻找字符串中的特定字符的位置方法

    python 巧用正则寻找字符串中的特定字符的位置方法

    下面小编就为大家分享一篇python 巧用正则寻找字符串中的特定字符的位置方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • Python中实现高效的列表过滤多种方法示例

    Python中实现高效的列表过滤多种方法示例

    这篇文章主要给大家介绍了关于Python中实现高效的列表过滤的多种方法,包括基础的for循环、列表推导式、filter函数、itertools模块,以及高级的pandas和numpy库,我们还讨论了生成器的使用,以及在实际场景中的应用,需要的朋友可以参考下
    2024-12-12
  • python tensorflow基于cnn实现手写数字识别

    python tensorflow基于cnn实现手写数字识别

    这篇文章主要为大家详细介绍了python tensorflow基于cnn实现手写数字识别,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • Python制作进度条的几种方法

    Python制作进度条的几种方法

    如果你之前没用过进度条,八成是觉得它会增加不必要的复杂性或者很难维护,其实不然。要加一个进度条其实只需要几行代码,快跟随小编一起学习学习吧
    2022-12-12
  • Python 执行矩阵与线性代数运算

    Python 执行矩阵与线性代数运算

    这篇文章主要介绍了Python 执行矩阵与线性代数运算,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-08-08
  • keras小技巧——获取某一个网络层的输出方式

    keras小技巧——获取某一个网络层的输出方式

    这篇文章主要介绍了keras小技巧——获取某一个网络层的输出方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-05-05
  • 使用Django启动命令行及执行脚本的方法

    使用Django启动命令行及执行脚本的方法

    今天小编就为大家分享一篇使用Django启动命令行及执行脚本的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • 详解numpy矩阵的创建与数据类型

    详解numpy矩阵的创建与数据类型

    这篇文章主要介绍了详解numpy矩阵的创建与数据类型,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • python语言使用技巧分享

    python语言使用技巧分享

    下面小编就为大家带来一篇python语言使用技巧分享。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05
  • 解决python ThreadPoolExecutor 线程池中的异常捕获问题

    解决python ThreadPoolExecutor 线程池中的异常捕获问题

    这篇文章主要介绍了解决python ThreadPoolExecutor 线程池中的异常捕获问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04

最新评论