PyQt5 显示超清高分辨率图片的方法


Posted in Python onApril 11, 2021

昨天写程序遇到一个问题,pyqt5 加载常规的图片完全可以显示。可当加载超清的高分辨率图片时,只能显示一个小角落。可我就想把一张 3840x2160 的图片加载到一个 800x600 的标签里该怎么办呢?如何自适应放缩尺寸,国内社区众所周知大多是抄袭,没什么解决方案;外网站搜了一下也没找到现成的解决方案,我知道又到了我开坑的时候了。

常规加载

先来看一下,如何借助 QLabel 和 QFileDialog 加载低分辨率的图片,这时候时能正常显示的。

import sys
from PyQt5.QtWidgets import (QMainWindow, QWidget, QHBoxLayout, QApplication, 
                             QPushButton, QLabel, QFileDialog, QVBoxLayout, 
                             QLineEdit)
from PyQt5.QtGui import QPixmap


class mainwindow(QMainWindow):
    def __init__(self):
        super(mainwindow, self).__init__()

        layout = QVBoxLayout()
        w = QWidget()
        w.setLayout(layout)
        self.setCentralWidget(w)

        self.image_label = QLabel()
        self.image_label.setFixedSize(800, 500)
        layout.addWidget(self.image_label)

        tmp_layout = QHBoxLayout()
        btn = QPushButton("选择图片路径")
        tmp_layout.addWidget(btn)
        btn.clicked.connect(self.load_image)

        self.result = QLineEdit()
        self.result.setPlaceholderText("车牌展示")
        self.result.setReadOnly(True)
        tmp_layout.addWidget(self.result)
        layout.addLayout(tmp_layout)

    def load_image(self):
        fname, _ = QFileDialog.getOpenFileName(self, 'Open File', 
                    'C://', "Image files (*.jpg *.png)")
        if fname is not None:
            pixmap = QPixmap(fname)
            self.image_label.setPixmap(pixmap)

if __name__ == '__main__':
    app = QApplication([])
    m = mainwindow()
    m.show()
    sys.exit(app.exec())

上述代码中,点击『选择图片路径』按钮就会调用文件对话框,选择图片后就会打开。步骤为:

  1. 第一步,QFileDialog 选择文件路径
  2. 第二步,将文件路径传入 QPixmap 类,通过重载构造一个对象,文档原话:Constructs a pixmap from the file with the given fileName. If the file does not exist or is of an unknown format, the pixmap becomes a null pixmap.
  3. 第三步,将 QPixmap 对象传给标签的 setPixmap 方法,就完成了图片的显示。

对于低分辨率图片,加载是没问题的:

PyQt5 显示超清高分辨率图片的方法

但高分辨率的图片,只能显示一个角落,也就是蓝色框那一部分:

PyQt5 显示超清高分辨率图片的方法

如何解决呢?既然国内外都没有现成的解决方案,只能掏出万能的官方文档了。

QImageReader 类

需要注意的是官方文档的语言是 C++,还好我会C++。打开文档,映入眼帘的就四句话:

  • QImageReader reader("large.jpeg"); 读取图片
  • reader.size(); 图片尺寸
  • reader.setClipRect(myRect); 图片裁剪
  • reader.setScaledSize(mySize); 设置图片尺寸,文档原话:Another common function is to show a smaller version of the image. Loading a very large image and then scaling it down to the approriate size can be a very memory consuming operation. By calling the QImageReader::setScaledSize function, you can set the size that you want your resulting image to be.

剩下的任务就很简单了,读图片,设置尺寸,显示。

import sys, time
from PyQt5.QtWidgets import (QMainWindow, QWidget, QHBoxLayout, QApplication, 
                             QPushButton, QLabel, QFileDialog, QVBoxLayout, 
                             QLineEdit)
from PyQt5.QtGui import QPixmap, QFont
from PyQt5.Qt import QSize, QImageReader
import qdarkstyle


class mainwindow(QMainWindow):
    def __init__(self):
        super(mainwindow, self).__init__()

        layout = QVBoxLayout()
        w = QWidget()
        w.setLayout(layout)
        self.setCentralWidget(w)

        self.image_label = QLabel()
        self.image_label.setFixedSize(800, 500)
        layout.addWidget(self.image_label)

        tmp_layout = QHBoxLayout()
        btn = QPushButton("选择图片路径")
        tmp_layout.addWidget(btn)
        btn.clicked.connect(self.load_image)

        self.result = QLineEdit()
        self.result.setPlaceholderText("车牌展示")
        self.result.setReadOnly(True)
        tmp_layout.addWidget(self.result)
        layout.addLayout(tmp_layout)

        self.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())

    def load_image(self):
        fname, _ = QFileDialog.getOpenFileName(self, 'Open File', 
                   'C://', "Image files (*.jpg *.png)")
        if fname is not None:
            # 还需要对图片进行重新调整大小
            img = QImageReader(fname)
            scale = 800 / img.size().width()
            height = int(img.size().height() * scale)
            img.setScaledSize(QSize(800, height))
            img = img.read()
            # 打开设置好的图片
            pixmap = QPixmap(img)
            self.image_label.setPixmap(pixmap)
            self.result.setText("车牌号放到这里")


if __name__ == '__main__':
    app = QApplication([])
    font = QFont()
    font.setFamily("SimHei")
    font.setPointSize(14)
    app.setFont(font)
    m = mainwindow()
    m.show()
    sys.exit(app.exec())

考虑到可能会加载超清图像,为了方便对图片进行控制,不要采用 QImage 或 QPixmap,而是使用 QImageReader

代码解析:

  1. 创建 QImageReader 对象,方便对图片进行更多的操作
  2. 自适应伸缩,将宽度限定为 800,自适应计算高度应该是多少,而后设置要缩放的大小
  3. 将设置好的图像读入为 QImage 类型,而后程序里将其转为 QPixmap 类型
  4. 正常方法设置即可,超清图像完美被加载

PyQt5 显示超清高分辨率图片的方法

以上就是PyQt5 显示超清高分辨率图片的方法的详细内容,更多关于PyQt5 显示超清高分辨率图片的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
浅谈MySQL中的触发器
May 05 Python
Python制作豆瓣图片的爬虫
Dec 28 Python
python利用socketserver实现并发套接字功能
Jan 26 Python
用Python一键搭建Http服务器的方法
Jun 01 Python
Python面向对象之反射/自省机制实例分析
Aug 24 Python
Python图像滤波处理操作示例【基于ImageFilter类】
Jan 03 Python
python函数局部变量、全局变量、递归知识点总结
Nov 15 Python
python 实现绘制整齐的表格
Nov 18 Python
Python常用模块logging——日志输出功能(示例代码)
Nov 20 Python
opencv3/C++图像像素操作详解
Dec 10 Python
Python运行DLL文件的方法
Jan 17 Python
详解Python GUI编程之PyQt5入门到实战
Dec 10 Python
用Python提取PDF表格的方法
用Python提取PDF表格的方法
python实现自动化群控的步骤
Apr 11 #Python
python 调用js的四种方式
Apr 11 #Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
You might like
根德YB400的电路分析
2021/03/02 无线电
PHP 5.3.0 安装分析心得
2009/08/07 PHP
PHP正则表达式替换站点关键字链接后空白的解决方法
2014/09/16 PHP
46 个非常有用的 PHP 代码片段
2016/02/16 PHP
PHP中md5()函数的用法讲解
2019/03/30 PHP
返回对象在当前级别中是第几个元素的实现代码
2011/01/20 Javascript
使用jQuery实现dropdownlist的联动效果(sharepoint 2007)
2011/03/30 Javascript
jquery获取自定义属性(attr和prop)实例介绍
2013/04/21 Javascript
JS父页面与子页面相互传值方法
2014/03/05 Javascript
jQuery中innerWidth()方法用法实例
2015/01/19 Javascript
javascript数据类型验证方法
2015/12/31 Javascript
js 获取站点应用名的简单实例
2016/08/18 Javascript
JS添加或修改控件的样式(Class)实现方法
2016/10/15 Javascript
AngularJS 限定$scope的范围实例详解
2017/06/23 Javascript
React Native实现进度条弹框的示例代码
2017/07/17 Javascript
JS中appendChild追加子节点无效的解决方法
2018/10/14 Javascript
Vue 通过公共字段,拼接两个对象数组的实例
2019/11/07 Javascript
js布局实现单选按钮控件
2020/01/17 Javascript
node.js中path路径模块的使用方法实例分析
2020/02/13 Javascript
JS 逻辑判断不要只知道用 if-else 和 switch条件判断(小技巧)
2020/05/27 Javascript
matplotlib设置legend图例代码示例
2017/12/19 Python
Django中针对基于类的视图添加csrf_exempt实例代码
2018/02/11 Python
python 高效去重复 支持GB级别大文件的示例代码
2018/11/08 Python
使用python3调用wxpy模块监控linux日志并定时发送消息给群组或好友
2019/06/05 Python
详解使用django-mama-cas快速搭建CAS服务的实现
2019/10/30 Python
Python如何实现自带HTTP文件传输服务
2020/07/08 Python
J2EE是技术还是平台还是框架
2016/08/14 面试题
建筑施工实习自我鉴定
2013/09/19 职场文书
直接有效的自我评价
2014/01/11 职场文书
家长会主持词
2014/03/26 职场文书
求职自我推荐信
2014/06/25 职场文书
单位法定代表人授权委托书
2014/09/20 职场文书
党员自评材料范文
2014/12/17 职场文书
2015年暑期社会实践活动总结
2015/03/27 职场文书
观看《信仰》心得体会
2016/01/15 职场文书