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实现堆栈与队列的方法
Jan 15 Python
Python制作词云的方法
Jan 03 Python
用Eclipse写python程序
Feb 10 Python
Python读取数据集并消除数据中的空行方法
Jul 12 Python
实例分析python3实现并发访问水平切分表
Sep 29 Python
Python Flask 搭建微信小程序后台详解
May 06 Python
python 应用之Pycharm 新建模板默认添加编码格式-作者-时间等信息【推荐】
Jun 17 Python
在python中计算ssim的方法(与Matlab结果一致)
Dec 19 Python
浅谈pymysql查询语句中带有in时传递参数的问题
Jun 05 Python
基于matplotlib中ion()和ioff()的使用详解
Jun 16 Python
python和js交互调用的方法
Jun 23 Python
利用python实时刷新基金估值(摸鱼小工具)
Sep 15 Python
用Python提取PDF表格的方法
用Python提取PDF表格的方法
python实现自动化群控的步骤
Apr 11 #Python
python 调用js的四种方式
Apr 11 #Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
You might like
php MessagePack介绍
2013/10/06 PHP
关于laravel 子查询 & join的使用
2019/10/16 PHP
javascript 短路法代码精简
2009/08/20 Javascript
jquery 卷帘效果实现代码(不同方向)
2013/02/05 Javascript
解决javascript:window.close()在chrome,Firefox下失效的问题
2013/05/07 Javascript
Javascript级联下拉菜单以及AJAX数据验证核心代码
2013/05/10 Javascript
js浮动图片的动态效果
2013/07/10 Javascript
jquery遍历数组与筛选数组的方法
2013/11/05 Javascript
javascript数组详解
2014/10/22 Javascript
jquery实现动态操作select选中
2015/02/11 Javascript
vue+element实现批量删除功能的示例
2018/02/28 Javascript
使用vue2实现购物车和地址选配功能
2018/03/29 Javascript
Angular5中提取公共组件之radio list的实例代码
2018/07/10 Javascript
js实现随机点名器精简版
2020/06/29 Javascript
解决VUE自定义拖拽指令时 onmouseup 与 click事件冲突问题
2020/07/24 Javascript
[02:17]2016国际邀请赛中国区预选赛VG战队领队采访
2016/06/26 DOTA
python实现从网络下载文件并获得文件大小及类型的方法
2015/04/28 Python
详解Python中for循环的使用方法
2015/05/14 Python
python实现颜色空间转换程序(Tkinter)
2015/12/31 Python
详解Python中的type和object
2018/08/15 Python
Python数据类型之列表和元组的方法实例详解
2019/07/08 Python
python面向对象 反射原理解析
2019/08/12 Python
Python传递参数的多种方式(小结)
2019/09/18 Python
python使用正则来处理各种匹配问题
2019/12/22 Python
pyinstaller还原python代码过程图解
2020/01/08 Python
tensorflow实现在函数中用tf.Print输出中间值
2020/01/21 Python
Python字符串格式化常用手段及注意事项
2020/06/17 Python
Python判断字符串是否为合法标示符操作
2020/09/03 Python
HTML5之tabindex属性全面解析
2016/07/07 HTML / CSS
使用layui框架实现点击左侧导航切换右侧内容且右侧选项卡跟随变化的效果
2020/11/10 HTML / CSS
阿联酋网上花店:Ferns N Petals
2018/02/14 全球购物
优秀大学生求职自荐信范文
2014/04/19 职场文书
大学班级学风建设方案
2014/05/01 职场文书
正风肃纪查摆剖析材料
2014/10/10 职场文书
2015年前台个人工作总结
2015/04/03 职场文书
微信小程序实现录音Record功能
2021/05/09 Javascript