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 相关文章推荐
在python的类中动态添加属性与生成对象
Sep 17 Python
详解Python使用tensorflow入门指南
Feb 09 Python
django 在原有表格添加或删除字段的实例
May 27 Python
python内置数据类型之列表操作
Nov 12 Python
详解Python logging调用Logger.info方法的处理过程
Feb 12 Python
python global关键字的用法详解
Sep 05 Python
python修改FTP服务器上的文件名
Sep 11 Python
Python3并发写文件与Python对比
Nov 20 Python
python 实现方阵的对角线遍历示例
Nov 29 Python
python判断两个序列的成员是否一样的实例代码
Mar 01 Python
Python编程根据字典列表相同键的值进行合并
Oct 05 Python
Python爬虫网络请求之代理服务器和动态Cookies
Apr 12 Python
用Python提取PDF表格的方法
用Python提取PDF表格的方法
python实现自动化群控的步骤
Apr 11 #Python
python 调用js的四种方式
Apr 11 #Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
You might like
写出高质量的PHP程序
2012/02/04 PHP
win7计划任务定时执行PHP脚本设置图解
2014/05/09 PHP
php查找字符串出现次数的方法
2014/12/01 PHP
怎么用javascript进行拖拽
2006/07/20 Javascript
js下用层来实现select的title提示属性
2010/02/23 Javascript
node.js入门教程迷你书、node.js入门web应用开发完全示例
2014/04/06 Javascript
JS实现动态移动层及拖动浮层关闭的方法
2015/04/30 Javascript
百度地图API之本地搜索与范围搜索
2015/07/30 Javascript
jQuery绑定自定义事件的魔法升级版
2016/06/30 Javascript
js创建数组的简单方法
2016/07/27 Javascript
快速使用node.js进行web开发详解
2017/04/26 Javascript
angularjs利用directive实现移动端自定义软键盘的示例
2017/09/20 Javascript
深入理解requireJS-实现一个简单的模块加载器
2018/01/15 Javascript
vue解决使用webpack打包后keep-alive不生效的方法
2018/09/01 Javascript
js正则取值的结果数组调试方法
2018/10/10 Javascript
小程序实现新用户判断并跳转激活的方法
2019/05/20 Javascript
JavaScript的变量声明与声明提前用法实例分析
2019/11/26 Javascript
从零学python系列之数据处理编程实例(一)
2014/05/22 Python
Python调用ctypes使用C函数printf的方法
2017/08/23 Python
基于python select.select模块通信的实例讲解
2017/09/21 Python
Python(Django)项目与Apache的管理交互的方法
2018/05/16 Python
详解Python安装tesserocr遇到的各种问题及解决办法
2019/03/07 Python
解决Mac下使用python的坑
2019/08/13 Python
pytorch numpy list类型之间的相互转换实例
2019/08/18 Python
Python Flask异步发送邮件实现方法解析
2020/08/01 Python
python获得命令行输入的参数的两种方式
2020/11/02 Python
表单button的outline在firefox浏览器下的问题
2012/12/24 HTML / CSS
美国在线印刷公司:PsPrint
2017/10/12 全球购物
请问如下代码执行后a和b的值分别是什么
2016/05/05 面试题
如果让你测试一台高速激光打印机,你都会进行哪些测试
2012/12/04 面试题
老师自我鉴定范文
2013/12/25 职场文书
《路旁的橡树》教学反思
2014/04/07 职场文书
企业承诺书格式范文
2015/04/28 职场文书
大学生暑假实习总结
2015/07/13 职场文书
MySQL表的增删改查基础教程
2021/04/07 MySQL
排查MySQL生产环境索引没有效果
2022/04/11 MySQL