如何使用PyQt5对PIL图像进行打印预览?
使用QPrintPreviewDialog实现PIL图像打印预览的方法
Qt打印相关组件原生仅支持Qt框架自身的图像格式,实现PIL图像的打印预览核心是先完成PIL Image到QImage的格式转换,再绑定QPrintPreviewDialog的绘制信号完成图像渲染。
前置依赖
需先安装对应运行库:
- 如使用PyQt5:
pip install pyqt5 pillow - 如使用PyQt6:
pip install pyqt6 pillow,接口差异极小,仅需调整导入路径即可适配。
完整实现示例
from PIL import Image from PyQt5.QtGui import QImage, QPainter from PyQt5.QtPrintSupport import QPrintPreviewDialog, QPrinter from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton import sys class PrintPreviewDemo(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("PIL图像打印预览") self.resize(400, 300) # 触发预览的按钮 preview_btn = QPushButton("打开打印预览", self) preview_btn.move(140, 130) preview_btn.clicked.connect(self.open_preview) # 加载待预览的PIL图像,此处替换为你的实际图像路径或PIL对象 self.target_pil_img = Image.open("test_image.png") # 如为RGBA透明图像可保留convert("RGBA"),对应调整下方QImage格式即可 # self.target_pil_img = Image.open("test_image.png").convert("RGBA") def pil2qimage(self, pil_img): """PIL图像转QImage格式""" img_format = QImage.Format_RGB888 if pil_img.mode == "RGBA": img_format = QImage.Format_RGBA8888 img_byte_data = pil_img.tobytes("raw", pil_img.mode) q_img = QImage( img_byte_data, pil_img.width, pil_img.height, pil_img.width * len(pil_img.mode), img_format ) return q_img def render_img_to_printer(self, printer): """将图像绘制到打印设备上""" painter = QPainter(printer) # 获取打印页面的可绘制区域尺寸 page_draw_area = printer.pageRect(QPrinter.DevicePixel) q_img = self.pil2qimage(self.target_pil_img) img_size = q_img.size() # 计算等比缩放比例,保证图像完整显示且不变形 scale_ratio = min( page_draw_area.width() / img_size.width(), page_draw_area.height() / img_size.height() ) # 计算居中偏移量 offset_x = (page_draw_area.width() - img_size.width() * scale_ratio) / 2 offset_y = (page_draw_area.height() - img_size.height() * scale_ratio) / 2 # 执行绘制 painter.translate(offset_x, offset_y) painter.scale(scale_ratio, scale_ratio) painter.drawImage(0, 0, q_img) painter.end() def open_preview(self): """打开打印预览窗口""" printer = QPrinter(QPrinter.HighResolution) preview_dialog = QPrintPreviewDialog(printer, self) # 绑定预览绘制信号,预览时自动调用渲染方法 preview_dialog.paintRequested.connect(self.render_img_to_printer) # 显示预览窗口,内置打印、页面设置、缩放预览等功能 preview_dialog.exec_() if __name__ == "__main__": app = QApplication(sys.argv) demo = PrintPreviewDemo() demo.show() sys.exit(app.exec_())
关键注意点
- 格式转换时要适配PIL图像的mode,透明通道的图像不要直接转RGB,否则会出现颜色异常
- 绘制时优先按打印页面的尺寸做等比缩放,避免图像被拉伸变形或超出页面范围
- QPrintPreviewDialog自带打印触发、页面边距设置、多页预览等原生功能,无需额外实现对应逻辑
内容的提问来源于stack exchange,提问作者KingOfTNT10
相关产品推荐
相关产品推荐

