Python自制一个PDF转PNG图片小工具
作者:Sir 发布时间:2023-07-24 11:40:12
标签:Python,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_())
来源:https://mp.weixin.qq.com/s/CEZ17Yco4iA_PUIn2wijDA


猜你喜欢
- 举个例子来说,要查找出2007-10-12至2007-10-31之间在网站上注册的会员,选择好日期后,点击“查询”按钮,发现2007-10-
- rpclib 是一个非常好用的 python webservice 库,可以动态的生成 wsdl, 不过这个项目已经基本停止,并被一个新的项
- 本文实例讲述了基于Python开发chrome插件的方法。分享给大家供大家参考,具体如下:谷歌Chrome插件是使用HTML、JavaScr
- 最近看到N多介绍CSS框架,前些天我说过一句话:“在我有限的视野里,还没见到可以真正可以称得上css框架的东东~”,当然也可能是我的视野太小
- 本文实例为大家分享了python opencv实现图像配准与比较的具体代码,供大家参考,具体内容如下代码 from skimage
- 功能介绍 (需要版本5.0.45)大数据操作ORM性能瓶颈在实体转换上面,并且不能使用常规的Sql去实现当列越多转换越慢,SqlSugar将
- 在Google上搜一下,可以发现一大堆对ASP不好的评价,什么运行速度慢、异常处理机制不好、缺乏面向对象机制、开发效率低、漏洞多等等。为了让
- 用for循环和海龟绘图实现漂亮的螺旋线A.课程内容本节课通过绘制复杂的螺旋线来深入学习for循环和range()函数的用法。深入了解循环的程
- 在大多数情况下,攻击者可以通过定位域管理员所登录的服务器,利用漏洞获取服务器system权限,找到域管理的账号、进程或是身份验证令牌,从而获
- 1. 功能说明,在页面使用smarty循环100次输出,类似for循环100次{section name=total loop=100}{$
- 本文实例为大家分享了Python时间戳使用和相互转换的具体代码,供大家参考,具体内容如下1.将字符串的时间转换为时间戳方法: &n
- 1.首先注册应用,获取 appkey、appsecretapi_url = "https://oapi.dingtalk.com/
- 概述np.ones()函数返回给定形状和数据类型的新数组,其中元素的值设置为1。此函数与numpy zeros()函数非常相似。用法np.o
- // 获取字符串的字节长度function len(s) {s = String(s);return s.length + (s.match
- 这是不久前写的一个分页存储过程,可应用于SQL Server 2005上面: if object_ID('[proc_SelectF
- 一、 排序的基本使用在查询数据时,如果没有使用排序操作,默认情况下SQL会按元组添加的顺序来排列查询结果。在SQL中,使用关键字 ORDER
- 需求表格实现行拖拽,要求只支持同级拖拽!实现使用插件:SortableJS,可以参考官网配置项!// 安装npm install sorta
- 指定变量类型有时您可能需要为变量指定类型,这可以通过 casting 来完成,Python 是一门面向对象的语言,因此它使用类来定义数据类型
- 环境:xadmin-for-python3 python3.5.2 django1.9.12问题描述:Product ProductSku两
- 自定义指令directives及常用钩子函数说明除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指