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的Flask框架中使用模版的入门教程
Apr 20 Python
Python实例一个类背后发生了什么
Feb 09 Python
python使用pymysql实现操作mysql
Sep 13 Python
Python文件循环写入行时防止覆盖的解决方法
Nov 09 Python
Python将string转换到float的实例方法
Jul 29 Python
python3 实现的对象与json相互转换操作示例
Aug 17 Python
关于PyTorch 自动求导机制详解
Aug 18 Python
python3多线程知识点总结
Sep 26 Python
Windows上安装tensorflow  详细教程(图文详解)
Feb 04 Python
python中有帮助函数吗
Jun 19 Python
Jupyter notebook 更改文件打开的默认路径操作
May 21 Python
Python如何让字典保持有序排列
Apr 29 Python
用Python提取PDF表格的方法
用Python提取PDF表格的方法
python实现自动化群控的步骤
Apr 11 #Python
python 调用js的四种方式
Apr 11 #Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
You might like
ThinkPHP空模块和空操作详解
2014/06/30 PHP
PHP读书笔记_运算符详解
2016/07/01 PHP
Zend Framework处理Json数据方法详解
2016/12/09 PHP
Git命令之分支详解
2021/03/02 PHP
提交表单时执行func方法实现代码
2013/03/17 Javascript
JS简单实现文件上传实例代码(无需插件)
2013/11/15 Javascript
php,js,css字符串截取的办法集锦
2014/09/26 Javascript
jquery $.trim()去除字符串空格的实现方法【附图例】
2016/03/30 Javascript
Bootstrap实现弹性搜索框
2016/07/11 Javascript
Angular中使用ui router实现系统权限控制及开发遇到问题
2016/09/23 Javascript
Mac下使用charles遇到的问题以及解决办法
2017/01/10 Javascript
理解javascript async的用法
2017/08/22 Javascript
vue 中动态绑定class 和 style的方法代码详解
2018/06/01 Javascript
使用js实现将后台传入的json数据放在前台显示
2018/08/06 Javascript
vue项目打包上传github并制作预览链接(pages)
2019/04/19 Javascript
js面向对象方式实现拖拽效果
2021/03/03 Javascript
python中函数默认值使用注意点详解
2016/06/01 Python
python rsa 加密解密
2017/03/20 Python
pandas通过loc生成新的列方法
2018/11/28 Python
简单了解Python matplotlib线的属性
2019/06/29 Python
详解pandas中MultiIndex和对象实际索引不一致问题
2019/07/23 Python
Python使用itchat模块实现群聊转发,自动回复功能示例
2019/08/26 Python
对Matlab中共轭、转置和共轭装置的区别说明
2020/05/11 Python
Python基于Twilio及腾讯云实现国际国内短信接口
2020/06/18 Python
Django REST 异常处理详解
2020/07/15 Python
Django+Uwsgi+Nginx如何实现生产环境部署
2020/07/31 Python
墨西哥运动服饰和鞋网上商店:Netshoes墨西哥
2016/07/28 全球购物
附答案的Java面试题
2012/11/19 面试题
仓库主管岗位职责
2014/03/02 职场文书
生日寄语大全
2014/04/08 职场文书
机关驾驶员违规检讨书
2014/09/13 职场文书
2014年检验员工作总结
2014/11/19 职场文书
2015年教师新年寄语
2014/12/08 职场文书
鸟的天堂导游词
2015/01/31 职场文书
酒店工程部主管岗位职责
2015/04/16 职场文书
《认识钟表》教学反思
2016/02/16 职场文书