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设计模式编程之工厂方法模式的使用
Mar 02 Python
Python使用Redis实现作业调度系统(超简单)
Mar 22 Python
PyQt5利用QPainter绘制各种图形的实例
Oct 19 Python
pandas DataFrame 交集并集补集的实现
Jun 24 Python
python实现函数极小值
Jul 10 Python
python3.6 tkinter实现屏保小程序
Jul 30 Python
pyinstaller打包opencv和numpy程序运行错误解决
Aug 16 Python
python实现回旋矩阵方式(旋转矩阵)
Dec 04 Python
python求最大公约数和最小公倍数的简单方法
Feb 13 Python
Spark处理数据排序问题如何避免OOM
May 21 Python
pytorch实现线性回归以及多元回归
Apr 11 Python
Python破解极验滑动验证码详细步骤
May 21 Python
用Python提取PDF表格的方法
用Python提取PDF表格的方法
python实现自动化群控的步骤
Apr 11 #Python
python 调用js的四种方式
Apr 11 #Python
Python WSGI 规范简介
使用pytorch实现线性回归
pytorch实现线性回归以及多元回归
You might like
如何用C语言编写PHP扩展的详解
2013/06/13 PHP
php实现批量上传数据到数据库(.csv格式)的案例
2017/06/18 PHP
php curl优化下载微信头像的方法总结
2018/09/07 PHP
javascript实现的鼠标链接提示效果生成器代码
2007/06/28 Javascript
javascript 在firebug调试时用console.log的方法
2012/05/10 Javascript
JQuery文字列表向上滚动的代码
2013/11/13 Javascript
轻松创建nodejs服务器(6):作出响应
2014/12/18 NodeJs
js实现a标签超链接提交form表单的方法
2015/06/24 Javascript
微信小程序 页面之间传参实例详解
2017/01/13 Javascript
js生成随机数方法和实例
2017/01/17 Javascript
vue component组件使用方法详解
2017/07/14 Javascript
vue iview组件表格 render函数的使用方法详解
2018/03/15 Javascript
JavaScript 2018 中即将迎来的新功能
2018/09/21 Javascript
vue中render函数的使用详解
2018/10/12 Javascript
微信小程序学习总结(四)事件与冒泡实例分析
2020/06/04 Javascript
vue-cli —— 如何局部修改Element样式
2020/10/22 Javascript
[01:08]DOTA2次级职业联赛 - Wings 战队宣传片
2014/12/01 DOTA
[01:46]2018完美盛典章节片——坚守
2018/12/17 DOTA
Python提示[Errno 32]Broken pipe导致线程crash错误解决方法
2014/11/19 Python
Python实现网站注册验证码生成类
2017/06/08 Python
python+matplotlib绘制简单的海豚(顶点和节点的操作)
2018/01/02 Python
python3 破解 geetest(极验)的滑块验证码功能
2018/02/24 Python
解决Python3 被PHP程序调用执行返回乱码的问题
2019/02/16 Python
python 动态渲染 mysql 配置文件的示例
2020/11/20 Python
美国东北部户外服装和设备零售商:Eastern Mountain Sports
2016/10/05 全球购物
英国在线药房和在线药剂师:Chemist 4 U
2020/01/05 全球购物
大唐电信科技股份有限公司java工程师面试经历
2016/12/09 面试题
简述进程的启动、终止的方式以及如何进行进程的查看
2014/02/20 面试题
简述Linux文件系统通过i节点把文件的逻辑结构和物理结构转换的工作过程
2016/01/06 面试题
学校安全教育制度
2014/01/31 职场文书
导游个人求职信
2014/04/25 职场文书
迎七一演讲稿
2014/09/12 职场文书
2014年信息宣传工作总结
2014/12/18 职场文书
《梅花魂》教学反思
2016/02/18 职场文书
哪类餐饮行业,最适合在高校创业?
2019/08/19 职场文书
pandas中DataFrame数据合并连接(merge、join、concat)
2021/05/30 Python