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 01 Python
Python 常用 PEP8 编码规范详解
Jan 22 Python
通过源码分析Python中的切片赋值
May 08 Python
Python计时相关操作详解【time,datetime】
May 26 Python
Django实现全文检索的方法(支持中文)
May 14 Python
Python OpenCV对本地视频文件进行分帧保存的实例
Jan 08 Python
解决pycharm的Python console不能调试当前程序的问题
Jan 20 Python
Django之创建引擎索引报错及解决详解
Jul 17 Python
python 串口读取+存储+输出处理实例
Dec 26 Python
10个python3常用排序算法详细说明与实例(快速排序,冒泡排序,桶排序,基数排序,堆排序,希尔排序,归并排序,计数排序)
Mar 17 Python
Python2手动安装更新pip过程实例解析
Jul 16 Python
python查询MySQL将数据写入Excel
Oct 29 Python
用Python提取PDF表格的方法
用Python提取PDF表格的方法
python实现自动化群控的步骤
Apr 11 #Python
python 调用js的四种方式
Apr 11 #Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
You might like
学习php过程中的一些注意点的总结
2013/10/25 PHP
php分享朋友圈的实现代码
2019/02/18 PHP
为超链接加上disabled后的故事
2010/12/10 Javascript
P3P Header解决Cookie跨域的问题
2013/03/12 Javascript
jquery validate 自定义验证方法介绍 日期验证
2014/02/27 Javascript
如何调试异步加载页面里包含的js文件
2014/10/30 Javascript
IE中鼠标经过option触发mouseout的解决方法
2015/01/29 Javascript
jQuery手机浏览器中拖拽动作的艰难性分析
2015/02/04 Javascript
javascript运算符——逻辑运算符全面解析
2016/06/27 Javascript
JavaScript cookie详解及简单实例应用
2016/12/31 Javascript
Jquery树插件zTree实现菜单树
2017/01/24 Javascript
js实现日历与定时器
2017/02/22 Javascript
JS模拟超市简易收银台小程序代码解析
2017/08/18 Javascript
JS如何设置元素样式的方法示例
2017/08/28 Javascript
JavaScript 通过Ajax 动态加载CheckBox复选框
2017/08/31 Javascript
web前端开发中常见的多列布局解决方案整理(一定要看)
2017/10/15 Javascript
[原创]微信小程序获取网络类型的方法示例
2019/03/01 Javascript
微信小程序实现的picker多级联动功能示例
2019/05/23 Javascript
Vue scrollBehavior 滚动行为实现后退页面显示在上次浏览的位置
2019/05/27 Javascript
ES6之Proxy的get方法详解
2019/10/11 Javascript
js实现超级玛丽小游戏
2020/03/18 Javascript
Python 字符串与二进制串的相互转换示例
2018/07/23 Python
Python实现的旋转数组功能算法示例
2019/02/23 Python
Python eval的常见错误封装及利用原理详解
2019/03/26 Python
python3用PIL把图片转换为RGB图片的实例
2019/07/04 Python
python3 sorted 如何实现自定义排序标准
2020/03/12 Python
Python中的Cookie模块如何使用
2020/06/04 Python
如何保障Web服务器安全
2014/05/05 面试题
数字天堂软件测试面试题
2012/12/23 面试题
EJB timer的种类
2014/10/28 面试题
寄语是什么意思
2014/04/10 职场文书
电子信息专业应届生自荐信
2014/06/04 职场文书
现实表现材料范文
2014/12/23 职场文书
2015年护士节慰问信
2015/03/23 职场文书
超级实用!五步法则,教你写好年终工作总结
2019/12/05 职场文书
Python识别花卉种类鉴定网络热门植物并自动整理分类
2022/04/08 Python