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 中 Meta Classes详解
Feb 13 Python
python中模块的__all__属性详解
Oct 26 Python
python2 与 pyhton3的输入语句写法小结
Sep 10 Python
python调用并链接MATLAB脚本详解
Jul 05 Python
Django使用unittest模块进行单元测试过程解析
Aug 02 Python
python实现按首字母分类查找功能
Oct 31 Python
SpringBoot实现登录注册常见问题解决方案
Mar 04 Python
构建高效的python requests长连接池详解
May 02 Python
python的pip有什么用
Jun 17 Python
Pycharm自动添加文件头注释和函数注释参数的方法
Oct 23 Python
如何向scrapy中的spider传递参数的几种方法
Nov 18 Python
移除Selenium中window.navigator.webdriver值
Jun 10 Python
用Python提取PDF表格的方法
用Python提取PDF表格的方法
python实现自动化群控的步骤
Apr 11 #Python
python 调用js的四种方式
Apr 11 #Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
You might like
Joomla实现组件中弹出一个模式(modal)窗口的方法
2016/05/04 PHP
PHP实现清除MySQL死连接的方法
2016/07/23 PHP
PHP+百度AI OCR文字识别实现了图片的文字识别功能
2019/05/08 PHP
javascript 获取HTML DOM父、子、临近节点
2014/06/16 Javascript
JsRender for object语法简介
2014/10/31 Javascript
JS实现文字掉落效果的方法
2015/05/06 Javascript
简介JavaScript中用于处理正切的Math.tan()方法
2015/06/15 Javascript
JS 获取HTML标签内的子节点的方法
2016/09/21 Javascript
动态JavaScript所造成一些你不知道的危害
2016/09/25 Javascript
SelecT下拉框选中和取值的解决方法
2016/11/22 Javascript
javascript稀疏数组(sparse array)和密集数组用法分析
2016/12/28 Javascript
jQuery html表格排序插件tablesorter使用方法详解
2017/02/10 Javascript
详解Angular-Cli中引用第三方库
2017/05/21 Javascript
实现图片首尾平滑轮播(JS原生方法—节流)
2017/10/17 Javascript
详解 vue better-scroll滚动插件排坑
2018/02/08 Javascript
JavaScript笛卡尔积超简单实现算法示例
2018/07/30 Javascript
vue.js实现简单的计算器功能
2020/02/22 Javascript
React实现轮播效果
2020/08/25 Javascript
python绘图方法实例入门
2015/05/19 Python
浅谈python中截取字符函数strip,lstrip,rstrip
2015/07/17 Python
Python使用Pycrypto库进行RSA加密的方法详解
2016/06/06 Python
关于反爬虫的一些简单总结
2017/12/13 Python
Python Selenium Cookie 绕过验证码实现登录示例代码
2018/04/10 Python
django的auth认证,authenticate和装饰器功能详解
2019/07/25 Python
如何基于Python实现电子邮件的发送
2019/12/16 Python
在keras下实现多个模型的融合方式
2020/05/23 Python
PIL.Image.open和cv2.imread的比较与相互转换的方法
2020/06/03 Python
Django实现内容缓存实例方法
2020/06/30 Python
浅析Python 条件控制语句
2020/07/15 Python
DRF框架API版本管理实现方法解析
2020/08/21 Python
Python中的None与 NULL(即空字符)的区别详解
2020/09/24 Python
SISLEY希思黎官方旗舰店:享誉全球的奢华植物美容品牌
2018/04/25 全球购物
数学系毕业生求职信
2014/05/29 职场文书
工作违纪检讨书范文
2015/01/26 职场文书
2016暑期社会实践新闻稿
2015/11/25 职场文书
导游词之西江千户苗寨
2019/12/24 职场文书