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计算已经过去多少个周末的方法
Jul 25 Python
Python编程实现删除VC临时文件及Debug目录的方法
Mar 22 Python
Python中的错误和异常处理简单操作示例【try-except用法】
Jul 25 Python
推荐10款最受Python开发者欢迎的Python IDE
Sep 16 Python
Python通过paramiko远程下载Linux服务器上的文件实例
Dec 27 Python
处理Selenium3+python3定位鼠标悬停才显示的元素
Jul 31 Python
Python3 字典dictionary入门基础附实例
Feb 10 Python
Matplotlib使用Cursor实现UI定位的示例代码
Mar 12 Python
Python插件机制实现详解
May 04 Python
Keras—embedding嵌入层的用法详解
Jun 10 Python
通俗易懂了解Python装饰器原理
Sep 17 Python
Python基于argparse与ConfigParser库进行入参解析与ini parser
Feb 02 Python
用Python提取PDF表格的方法
用Python提取PDF表格的方法
python实现自动化群控的步骤
Apr 11 #Python
python 调用js的四种方式
Apr 11 #Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
You might like
Sony CFR 320 修复改造
2020/03/14 无线电
php数据入库前清理 注意php intval与mysql的int取值范围不同
2010/12/12 PHP
php修改NetBeans默认字体的大小
2013/07/02 PHP
javascript显示选择目录对话框的代码
2008/11/10 Javascript
JavaScript中的6种运算符总结
2014/10/16 Javascript
JSONP之我见
2015/03/24 Javascript
JavaScript数据类型之基本类型和引用类型的值
2015/04/01 Javascript
javascript实现数组去重的多种方法
2016/03/14 Javascript
Javascript计算二维数组重复值示例代码
2016/12/18 Javascript
Vue组件中slot的用法
2018/01/30 Javascript
使用pkg打包Node.js应用的方法步骤
2018/10/19 Javascript
微信小程序引入Vant组件库过程解析
2019/08/06 Javascript
vue(2.x,3.0)配置跨域代理
2019/11/27 Javascript
微信域名检测接口调用演示步骤(含PHP、Python)
2019/12/08 Javascript
pytyon 带有重复的全排列
2013/08/13 Python
python通过装饰器检查函数参数数据类型的方法
2015/03/13 Python
Django分页查询并返回jsons数据(中文乱码解决方法)
2018/08/02 Python
利用python和百度地图API实现数据地图标注的方法
2019/05/13 Python
Python文件操作中进行字符串替换的方法(保存到新文件/当前文件)
2019/06/28 Python
python之拟合的实现
2019/07/19 Python
使用Python制作一个打字训练小工具
2019/10/01 Python
django自定义模板标签过程解析
2019/12/14 Python
Python3 main函数使用sys.argv传入多个参数的实现
2019/12/25 Python
Python中import导入不同目录的模块方法详解
2020/02/18 Python
Win 10下Anaconda虚拟环境的教程
2020/05/18 Python
Python调用ffmpeg开源视频处理库,批量处理视频
2020/11/16 Python
纯CSS实现设置半个字符的样式
2014/07/03 HTML / CSS
英国HYPE双肩包官网:英国本土时尚潮牌
2018/09/26 全球购物
高级方案规划工程师岗位职责
2013/11/29 职场文书
会计专业毕业生自荐信范文
2013/12/20 职场文书
成龙霸王洗发水广告词
2014/03/14 职场文书
个人四风对照检查材料
2014/09/26 职场文书
2014年班务工作总结
2014/12/02 职场文书
学前班学生评语
2014/12/29 职场文书
侵犯商业秘密的律师函
2015/05/27 职场文书
Nginx内网单机反向代理的实现
2021/11/07 Servers