You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 13:54:07