2人参与 • 2026-08-07 • Python

import sys
from pyqt6.qtcore import qt, qsize, qfileinfo
from pyqt6.qtgui import qimage, qpainter
# 低版本仅能导入这三个,去掉 qpdfdocumentloader
from pyqt6.qtpdf import qpdfdocument, qpdfdocumentrenderoptions
from pyqt6.qtwidgets import qapplication, qmainwindow, qpushbutton, qwidget, qvboxlayout
class mainwindow(qmainwindow):
def __init__(self, parent=none):
super().__init__(parent)
self.setwindowtitle("pdf转高清图片 pyqt6")
self.resize(400, 120)
central_widget = qwidget()
self.setcentralwidget(central_widget)
layout = qvboxlayout(central_widget)
self.btn_convert = qpushbutton("执行pdf转图片")
layout.addwidget(self.btn_convert)
self.btn_convert.clicked.connect(self.on_pushbutton_clicked)
def pdftohighresimage(self, pdfpath: str, imgpath: str, size: qsize, dpi: int) -> bool:
# 关键修复:传入self作为父对象,解决构造参数不足报错
doc = qpdfdocument(self)
err = doc.load(pdfpath)
if err != qpdfdocument.error.none_:
print(f"load pdf error code: {err}")
return false
# 校验自定义尺寸
if not size.isvalid() or size.width() <= 0 or size.height() <= 0:
print("input size width or height less zero!")
return false
# 拆分路径,自动创建目录
imagefileinfo = qfileinfo(imgpath)
suffix = imagefileinfo.suffix().lower()
imgformat = ""
quality = -1
if suffix == "png":
imgformat = "png"
elif suffix in ("jpg", "jpeg"):
imgformat = "jpg"
quality = 100
else:
print("unsupported image extensions, only png / jpg / jpeg are supported!")
return false
pageidx = 0
print(f"page point size: {doc.pagepointsize(pageidx)}")
opts = qpdfdocumentrenderoptions()
opts.setrenderflags(qpdfdocumentrenderoptions.renderflag.none_)
img = doc.render(pageidx, size, opts)
if img.isnull():
print(f"page {pageidx + 1} rendering failed!")
return false
# 白底画布
whitebgimg = qimage(size, qimage.format.format_rgb32)
whitebgimg.fill(qt.globalcolor.white)
painter = qpainter(whitebgimg)
painter.setrenderhints(qpainter.renderhint.antialiasing | qpainter.renderhint.textantialiasing)
painter.drawimage(0, 0, img)
painter.end()
img = whitebgimg
# dpi 设置
dotspermeter = round(dpi / 25.4 * 1000)
img.setdotspermeterx(dotspermeter)
img.setdotspermetery(dotspermeter)
if imgformat == "png":
img.settext("dpi", str(dpi))
saveok = false
if quality > 0:
saveok = img.save(imgpath, imgformat, quality)
else:
saveok = img.save(imgpath, imgformat)
if not saveok:
print(f"failed to save the image: {imgpath}")
else:
print(f"success to save the image: {imgpath}")
return saveok
def on_pushbutton_clicked(self):
self.pdftohighresimage("l000137362.pdf", "l000137362.jpg", qsize(896, 1534), 300)
self.pdftohighresimage("l000137362.pdf", "l000137362.png", qsize(896, 1534), 300)
if __name__ == "__main__":
app = qapplication(sys.argv)
win = mainwindow()
win.show()
sys.exit(app.exec())

pyqt6 的 pdf 模块提供了强大的 pdf 文档处理能力,主要包含在 qtpdf 模块中。该模块允许开发者加载、渲染、查看和操作 pdf 文档,是构建 pdf 阅读器、转换工具或文档处理应用的理想选择。
qpdfdocument 是 pdf 模块的核心类,负责加载和管理 pdf 文档。它提供了以下关键功能:
load() 方法从文件路径或 qbytearray 加载 pdf 文档pagepointsize())、页面标签等qimage 对象qpdfselection 配合)qpdfdocumentrenderoptions 控制 pdf 页面的渲染行为,可以设置:
setrenderflags() 设置渲染选项qpdfpagenavigator 提供页面导航功能,支持:
qpdfselection 表示 pdf 页面上的文本选择,可以:
from pyqt6.qtpdf import qpdfdocument
# 创建文档对象(需要传入父对象)
doc = qpdfdocument(parent=self)
# 加载 pdf 文件
error = doc.load("example.pdf")
# 检查加载结果
if error != qpdfdocument.error.none_:
print(f"加载失败,错误代码: {error}")
else:
print(f"pdf 加载成功,共 {doc.pagecount()} 页")
# 获取页面数量
page_count = doc.pagecount()
# 获取第一页的尺寸(以点为单位,1点=1/72英寸)
page_size = doc.pagepointsize(0) # qsizef 对象
print(f"页面尺寸: {page_size.width()} x {page_size.height()} 点")
# 转换为像素(假设 dpi=72)
dpi = 72
width_px = page_size.width() * dpi / 72
height_px = page_size.height() * dpi / 72
from pyqt6.qtpdf import qpdfdocumentrenderoptions
from pyqt6.qtgui import qimage
# 创建渲染选项
opts = qpdfdocumentrenderoptions()
opts.setrenderflags(qpdfdocumentrenderoptions.renderflag.none_)
# 设置目标尺寸(以像素为单位)
target_size = qsize(800, 600)
# 渲染第一页
image = doc.render(0, target_size, opts)
if not image.isnull():
print(f"渲染成功,图像尺寸: {image.width()} x {image.height()}")
# 保存图像
image.save("page_0.png", "png")
else:
print("渲染失败")
# 创建页面对象(需要 qpdfpagemodel 配合)
# 注意:文本提取功能相对有限,复杂布局可能无法正确提取
from pyqt6.qtpdf import qpdfpagemodel
page_model = qpdfpagemodel(doc)
if page_model.pagecount() > 0:
# 获取页面文本(简化示例,实际使用更复杂)
text = page_model.text(0)
print(f"页面文本: {text[:100]}...") # 显示前100个字符
opts = qpdfdocumentrenderoptions()
# 设置裁剪区域(渲染页面的一部分)
from pyqt6.qtcore import qrectf
crop_rect = qrectf(50, 50, 200, 300) # 左上角(50,50),宽200,高300
opts.setcroprect(crop_rect)
# 设置缩放
opts.setscalefactor(2.0) # 放大2倍
# 设置渲染标志
from pyqt6.qtpdf import qpdfdocumentrenderoptions
flags = (qpdfdocumentrenderoptions.renderflag.antialiasing |
qpdfdocumentrenderoptions.renderflag.textantialiasing)
opts.setrenderflags(flags)
def render_all_pages(doc, output_dir="output"):
import os
os.makedirs(output_dir, exist_ok=true)
for page_index in range(doc.pagecount()):
# 获取原始页面尺寸
page_size = doc.pagepointsize(page_index)
# 转换为像素(300 dpi)
dpi = 300
width = int(page_size.width() * dpi / 72)
height = int(page_size.height() * dpi / 72)
target_size = qsize(width, height)
# 渲染
opts = qpdfdocumentrenderoptions()
image = doc.render(page_index, target_size, opts)
if not image.isnull():
# 保存为png
filename = os.path.join(output_dir, f"page_{page_index:03d}.png")
image.save(filename, "png")
print(f"已保存: {filename}")
else:
print(f"页面 {page_index} 渲染失败")
from pyqt6.qtpdf import qpdfdocument
class pdfprocessor:
def __init__(self):
self.document = qpdfdocument()
def load_pdf(self, filepath):
error = self.document.load(filepath)
error_messages = {
qpdfdocument.error.none_: "成功",
qpdfdocument.error.filenotfounderror: "文件未找到",
qpdfdocument.error.invalidfileformaterror: "无效的文件格式",
qpdfdocument.error.incorrectpassworderror: "密码错误",
qpdfdocument.error.unsupportedsecurityschemeerror: "不支持的加密方案",
qpdfdocument.error.documentlockederror: "文档被锁定",
qpdfdocument.error.unknownerror: "未知错误"
}
if error in error_messages:
return error_messages[error]
else:
return f"未知错误代码: {error}"
对于大型pdf文档,建议在后台线程中进行渲染操作:
from pyqt6.qtcore import qthread, pyqtsignal
class renderthread(qthread):
finished = pyqtsignal(qimage, int) # 图像和页码
def __init__(self, doc, page_index, size):
super().__init__()
self.doc = doc
self.page_index = page_index
self.size = size
def run(self):
opts = qpdfdocumentrenderoptions()
image = self.doc.render(self.page_index, self.size, opts)
self.finished.emit(image, self.page_index)
对于pdf查看器应用,实现页面缓存可以显著提升性能:
class pdfviewercache:
def __init__(self, max_cache_size=10):
self.cache = {} # page_index -> qimage
self.max_size = max_cache_size
self.access_order = [] # 最近访问顺序
def get_page(self, page_index, doc, size):
if page_index in self.cache:
# 更新访问顺序
self.access_order.remove(page_index)
self.access_order.append(page_index)
return self.cache[page_index]
# 渲染新页面
opts = qpdfdocumentrenderoptions()
image = doc.render(page_index, size, opts)
# 添加到缓存
self.cache[page_index] = image
self.access_order.append(page_index)
# 清理旧缓存
if len(self.cache) > self.max_size:
oldest = self.access_order.pop(0)
del self.cache[oldest]
return image
对于高分辨率渲染,可以考虑渐进式加载:
def progressive_render(doc, page_index, final_size, steps=3):
"""渐进式渲染:从低分辨率开始,逐步提高"""
images = []
for step in range(1, steps + 1):
# 逐步增加尺寸
scale = step / steps
current_size = qsize(
int(final_size.width() * scale),
int(final_size.height() * scale)
)
opts = qpdfdocumentrenderoptions()
image = doc.render(page_index, current_size, opts)
images.append(image)
return images # 返回不同分辨率的图像序列
qpdfdocument 需要正确管理生命周期:
# 正确做法:设置父对象,自动管理内存
class pdfwidget(qwidget):
def __init__(self):
super().__init__()
self.doc = qpdfdocument(self) # 设置父对象
def load_pdf(self, path):
self.doc.load(path)
# 析构时自动释放
确保系统字体包含中文字符集,或指定字体:
from pyqt6.qtgui import qfont, qfontdatabase
# 加载中文字体
font_id = qfontdatabase.addapplicationfont("path/to/chinese_font.ttf")
if font_id != -1:
font_families = qfontdatabase.applicationfontfamilies(font_id)
if font_families:
chinese_font = qfont(font_families[0])
# 应用到渲染上下文
处理加密pdf需要密码:
def load_encrypted_pdf(filepath, password):
doc = qpdfdocument()
# 先尝试无密码加载
error = doc.load(filepath)
if error == qpdfdocument.error.incorrectpassworderror:
# 使用密码重试
# 注意:pyqt6的qpdfdocument目前没有直接的密码接口
# 可能需要通过其他方式处理加密pdf
print("需要密码解密")
return none
return doc
from pyqt6.qtwidgets import (qapplication, qmainwindow, qwidget,
qvboxlayout, qlabel, qscrollarea)
from pyqt6.qtpdf import qpdfdocument
from pyqt6.qtgui import qpixmap
class simplepdfviewer(qmainwindow):
def __init__(self):
super().__init__()
self.setwindowtitle("pdf查看器")
self.resize(800, 600)
self.doc = qpdfdocument(self)
self.current_page = 0
# 创建界面
central = qwidget()
self.setcentralwidget(central)
layout = qvboxlayout(central)
self.image_label = qlabel()
self.image_label.setalignment(qt.alignmentflag.aligncenter)
scroll = qscrollarea()
scroll.setwidget(self.image_label)
scroll.setwidgetresizable(true)
layout.addwidget(scroll)
# 加载pdf
self.load_pdf("document.pdf")
def load_pdf(self, filepath):
error = self.doc.load(filepath)
if error == qpdfdocument.error.none_:
self.show_page(0)
def show_page(self, page_index):
if 0 <= page_index < self.doc.pagecount():
self.current_page = page_index
# 渲染页面
page_size = self.doc.pagepointsize(page_index)
target_size = qsize(
int(page_size.width() * 2), # 放大显示
int(page_size.height() * 2)
)
opts = qpdfdocumentrenderoptions()
image = self.doc.render(page_index, target_size, opts)
if not image.isnull():
pixmap = qpixmap.fromimage(image)
self.image_label.setpixmap(pixmap)
self.setwindowtitle(f"pdf查看器 - 第 {page_index + 1} 页")
class pdftoimageconverter:
def __init__(self, dpi=300, output_format="png"):
self.dpi = dpi
self.output_format = output_format.upper()
def convert(self, pdf_path, output_dir):
import os
from pyqt6.qtpdf import qpdfdocument
doc = qpdfdocument()
if doc.load(pdf_path) != qpdfdocument.error.none_:
return false
os.makedirs(output_dir, exist_ok=true)
for i in range(doc.pagecount()):
page_size = doc.pagepointsize(i)
# 计算像素尺寸
width = int(page_size.width() * self.dpi / 72)
height = int(page_size.height() * self.dpi / 72)
# 渲染
opts = qpdfdocumentrenderoptions()
image = doc.render(i, qsize(width, height), opts)
if not image.isnull():
# 保存
filename = os.path.join(
output_dir,
f"page_{i:03d}.{self.output_format.lower()}"
)
if self.output_format == "jpg":
image.save(filename, "jpeg", 95) # 95%质量
else:
image.save(filename, self.output_format)
return true
pyqt6 的 pdf 模块提供了完整的 pdf 处理能力,从简单的文档加载和渲染到高级的文本提取和页面导航。关键点总结:
qpdfdocument 是基础,qpdfdocumentrenderoptions 控制渲染以上就是python+pyqt6实现将pdf文件转高清图片的详细内容,更多关于pyqt pdf转图片的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论