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 相关文章推荐
深入理解NumPy简明教程---数组3(组合)
Dec 17 Python
Python读取文件内容的三种常用方式及效率比较
Oct 07 Python
使用11行Python代码盗取了室友的U盘内容
Oct 23 Python
Ubuntu下Python2与Python3的共存问题
Oct 31 Python
python感知机实现代码
Jan 18 Python
浅析python的Lambda表达式
Feb 27 Python
Python将文字转成语音并读出来的实例详解
Jul 15 Python
python实现几种归一化方法(Normalization Method)
Jul 31 Python
python3 自动打印出最新版本执行的mysql2redis实例
Apr 09 Python
Expected conditions模块使用方法汇总代码解析
Aug 13 Python
详解基于python的图像Gabor变换及特征提取
Oct 26 Python
Pandas数据类型之category的用法
Jun 28 Python
用Python提取PDF表格的方法
用Python提取PDF表格的方法
python实现自动化群控的步骤
Apr 11 #Python
python 调用js的四种方式
Apr 11 #Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
You might like
用PHP调用数据库的存贮过程
2006/10/09 PHP
php 判断数组是几维数组
2013/03/20 PHP
php采集自中央气象台范围覆盖全国的天气预报代码实例
2015/01/04 PHP
JavaScript几种形式的树结构菜单
2010/05/10 Javascript
关于js new Date() 出现NaN 的分析
2012/10/23 Javascript
jquery实现tr元素的上下移动示例代码
2013/12/20 Javascript
刷新页面的几种方法小结(JS,ASP.NET)
2014/01/07 Javascript
table insertRow、deleteRow定义和用法总结
2014/05/14 Javascript
jquery实现左右滑动菜单效果代码
2015/08/27 Javascript
jQuery事件委托之Safari
2016/07/05 Javascript
AngularJS 模型详细介绍及实例代码
2016/07/27 Javascript
更靠谱的H5横竖屏检测方法(js代码)
2016/09/13 Javascript
jQuery 实现ajax传入参数含有特殊字符的方法总结
2016/10/17 Javascript
vuejs响应用户事件(如点击事件)
2017/03/14 Javascript
JS中type="button"和type="submit"的区别
2017/07/04 Javascript
vue resource post请求时遇到的坑
2017/10/19 Javascript
解决linux下node.js全局模块找不到的问题
2018/05/15 Javascript
vue中多路由表头吸顶实现的几种布局方式
2019/04/12 Javascript
js常用正则表达式集锦
2019/05/17 Javascript
详解webpack打包vue项目之后生成的dist文件该怎么启动运行
2019/09/06 Javascript
js贪心算法 钱币找零问题代码实例
2019/09/11 Javascript
js与jquery获取input输入框中的值实例讲解
2020/02/27 jQuery
详解js中的原型,原型对象,原型链
2020/07/16 Javascript
Python实现的生产者、消费者问题完整实例
2018/05/30 Python
Python3正则匹配re.split,re.finditer及re.findall函数用法详解
2018/06/11 Python
python 在指定范围内随机生成不重复的n个数实例
2019/01/28 Python
对Matlab中共轭、转置和共轭装置的区别说明
2020/05/11 Python
CSS3实现的炫酷菜单代码分享
2015/03/12 HTML / CSS
阿根廷网上配眼镜:SmartBuyGlasses阿根廷
2016/08/19 全球购物
HomeAway澳大利亚:预订你的度假屋,公寓、度假村、别墅等
2019/02/20 全球购物
美国轻奢时尚购物网站:REVOLVE(支持中文)
2020/07/18 全球购物
餐饮主管岗位职责
2013/12/10 职场文书
素食餐饮项目创业计划书
2014/02/02 职场文书
志愿者活动总结报告
2014/06/27 职场文书
教师党员个人总结
2015/02/10 职场文书
计算机教师工作总结
2015/08/13 职场文书