PyQt5 显示超清高分辨率图片的方法
作者:muyuuuu 发布时间:2021-07-11 04:16:09
目录
常规加载
QImageReader 类
昨天写程序遇到一个问题,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())
上述代码中,点击『选择图片路径』按钮就会调用文件对话框,选择图片后就会打开。步骤为:
第一步,QFileDialog 选择文件路径
第二步,将文件路径传入 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.
第三步,将 QPixmap 对象传给标签的 setPixmap 方法,就完成了图片的显示。
对于低分辨率图片,加载是没问题的:
但高分辨率的图片,只能显示一个角落,也就是蓝色框那一部分:
如何解决呢?既然国内外都没有现成的解决方案,只能掏出万能的官方文档了。
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
代码解析:
创建 QImageReader 对象,方便对图片进行更多的操作
自适应伸缩,将宽度限定为 800,自适应计算高度应该是多少,而后设置要缩放的大小
将设置好的图像读入为 QImage 类型,而后程序里将其转为 QPixmap 类型
正常方法设置即可,超清图像完美被加载
来源:https://muyuuuu.github.io/2021/04/10/pyqt5-load-huge-image/


猜你喜欢
- 本文实例讲述了Python进程池Pool应用。分享给大家供大家参考,具体如下:当需要创建的子进程数量不多时,可以直接利用multiproce
- 什么是insert buffer? 插入缓冲,也称之为insert buffer,它是innodb存储引擎的关键特性
- created页面加载未渲染html之前执行。mounted渲染html后再执行。由于created在html模板生产之前所以无法对Dom进
- 解包在英文里叫做 Unpacking,就是将容器里面的元素逐个取出来放在其它地方,好比你父母去菜市场买了一袋苹果回来分别发给家里的每个成员,
- 一般做法都是用aspjpeg的组件,这里有份用法说明,看一下吧。aspjpeg是一款非常强大的图片处理组件,纯英文版本。不过早已经有免费版和
- 锁有两种分类方法。(1) 从数据库系统的角度来看锁分为以下三种类型: •独占锁(Exclusive Lock)独占锁锁定的资源只允许进行锁定
- 这里有numpy数组的相关介绍https://www.jb51.net/article/130657.htm排序numpy与python列表
- 我们用python 打包的exe文件的时候,每次运行后面都有一个黑框框,比如我的这个:用tkinter做的图形界面,打包成exe文件,每次运
- 问题记录一下出现的问题, 数据翻倍这是复现问题的代码data() { return { space: "
- 如果说亲密性原则是对元素的归类组合,是将元素之间逻辑理解上的差异在视觉上表现出来,是属于信息分类的话,那么对齐原则即是在视觉上串起这些差异化
- 脚手架(vue-cli)(一)什么是脚手架概念:是一种用于快速开发Vue项目的系统架构优点:能够帮助咱们快速的开发项目缺点:由于脚手架适用于
- 在安装mha4mysql时,大概步骤是:解压,perl Makefile.PL,make, make install。在执行 perl Ma
- 本文实例讲述了Python实现模拟登录及表单提交的方法。分享给大家供大家参考。具体实现方法如下:# -*- coding: utf-8 -*
- 本文实例为大家分享了python使用tcp传输图片数据的具体代码,供大家参考,具体内容如下数据包格式如下客户端:import socketi
- 前言CORS 即 Cross Origin Resource Sharing 跨域资源共享.跨域请求分两种:简单请求、复杂请求.简单请求简单
- 熟悉SQL SERVER 2000的数据库管理员都知道,其DTS可以进行数据的导入导出,其实,我们也可以使用Transa
- 在你的 Django 应用中,你或许希望根据某字段的值对检索结果排序,比如说,按字母顺序。 那么,使用 order_by() 这个方法就可以
- 一、Can't connect to MySQL server on 'localhost'(10061
- 本文实例讲述了python实现从尾到头打印单链表操作。分享给大家供大家参考,具体如下:# coding=utf-8class SingleN
- 目录1.Python 变量的概述:2.Python 变量的命名3.Python 变量赋值3.1 Python 变量赋值概述3.2 Pytho