PySide(PyQt)实现鼠标画框局部放大

 按住鼠标左键画框,裁切画面并局部放大,可以用来生成ROI

 1、在QtDesigner中创建ui文件,命名为crop.ui:

2、自定义脚本ImageLabel.py :

from PySide6.QtCore import Qt, QRect, Signal, QPoint
from PySide6.QtGui import QPixmap, QPainter, QPen, QColor
from PySide6.QtWidgets import QLabelclass ImageLabel(QLabel):src_info = Signal(str)crop_info = Signal(str)show_info = Signal(str)def __init__(self, parent=None):super().__init__(parent)self.scale = 1.0  # 显示比例,其含义为当前的显示窗口的每个像素代表原始图几个像素self.src_width = 1self.src_height = 1self.showing_pixmap = QPixmap()  # 当前显示的图像内容(从原图原比例裁切而来)self.scaled_image = QPixmap()  # 当前显示的图像内容(经过缩放适应窗口的)self.scaled_image_x0 = 0  # 显示内容的x起点self.scaled_image_y0 = 0  # 显示内容的y起点self.erase = False  # 擦除已有的方框self.start_pos = QPoint()  # 鼠标起始点self.end_pos = QPoint()  # 鼠标结束点self.show_rect = QRect(0, 0, 1, 1)  # 显示窗口维度的方框self.crop_rect = QRect(0, 0, 1, 1)  # 实际像素维度的方框# 重新定义鼠标按下事件def mousePressEvent(self, event):if event.button() == Qt.LeftButton:self.start_pos = event.position().toPoint()self.erase = False# 重新定义鼠标移动事件def mouseMoveEvent(self, event):if self.start_pos:self.end_pos = event.position().toPoint()self.show_rect = QRect(self.start_pos, self.end_pos)self.update()# 重新定义鼠标松开事件def mouseReleaseEvent(self, event):if event.button() == Qt.LeftButton:self.end_pos = event.position().toPoint()self.show_rect = QRect(self.start_pos, self.end_pos)self.erase = True  # 这一行决定了松开鼠标后方框是否擦除self.normalize_rect()  # 将方框参数转成正数self.update()self.crop_image(self.showing_pixmap, self.show_rect)  # 裁切图像# 重新定义绘画事件def paintEvent(self, event):super().paintEvent(event)painter = QPainter(self)if not self.erase:  # 不擦除painter.setPen(QPen(QColor(255, 0, 0, 255), 1, Qt.SolidLine))else:  # 擦除(用透明色画一遍)painter.setPen(QPen(QColor(0, 0, 0, 0), 2, Qt.SolidLine))painter.drawRect(self.show_rect)# 将得到的方框的长宽尺寸转换成正数def normalize_rect(self):x = self.show_rect.x()y = self.show_rect.y()width = self.show_rect.width()height = self.show_rect.height()if width < 0:x += widthwidth = abs(width)if height < 0:y += heightheight = abs(height)# 最小方框self.show_rect = QRect(x, y, max(width, 3), max(height, 3))# 裁切并显示画面def crop_image(self, real_pixmap, showing_rect):  # 注意:pixmap是需要显示的真实像素维度的图像,rect是鼠标在屏幕显示维度上的方框# 将需要显示的图像进行满幅不变形缩放,并存储为显示图像self.scaled_image = real_pixmap.scaled(self.width(), self.height(), Qt.KeepAspectRatio,Qt.SmoothTransformation)# 显示倍率,含义为显示的窗口中,每像素相当于几个实际的像素self.scale = float(real_pixmap.width() / self.scaled_image.width())# 坐标变换,当在像素窗口中画方框,映射到显示图像中的相对坐标self.scaled_image_x0 = (self.width() - self.scaled_image.width()) / 2self.scaled_image_y0 = (self.height() - self.scaled_image.height()) / 2# 用以在实际像素的原图中裁切的方框self.crop_rect = QRect((showing_rect.x() - self.scaled_image_x0) * self.scale,(showing_rect.y() - self.scaled_image_y0) * self.scale,(showing_rect.width()) * self.scale,(showing_rect.height()) * self.scale)# 裁切到的用以显示的图像self.showing_pixmap = self.showing_pixmap.copy(self.crop_rect)# 再次缩放裁切到的的图像self.scaled_image = self.showing_pixmap.scaled(self.width(), self.height(), Qt.KeepAspectRatio,Qt.SmoothTransformation)  # 将需要显示的图像进行满幅不变形缩放,并存储为显示图像self.setPixmap(self.scaled_image)  # 显示图像self.setAlignment(Qt.AlignCenter)  # 居中显示# 再次计算显示倍率self.scale = self.showing_pixmap.height() / self.scaled_image.height()self.crop_info.emit(f'裁切到的尺寸:{str(self.showing_pixmap.width())} * {str(self.showing_pixmap.height())}')self.show_info.emit(f'显示像素:{str(self.scaled_image.width())} * {str(self.scaled_image.height())},显示倍率:{self.scale}')# 初始化,设置原图像def set_src(self, pixmap):self.src_width = pixmap.width()self.src_height = pixmap.height()self.showing_pixmap = pixmap.copy()# 满幅裁切self.crop_rect = QRect(0, 0, self.width(), self.height())self.crop_image(self.showing_pixmap, self.crop_rect)self.src_info.emit(f'原图尺寸:{str(self.src_width)} * {str(self.src_height)}')

3、在QtDesigner中添加“提升为”的自定义脚本,并且将显示用的窗口提升:

4、用pyui工具将ui文件生成py文件,并编写主程序:

# encoding: utf-8from PySide6.QtCore import QObject
from PySide6.QtWidgets import QApplication, QMainWindow
from PySide6.QtGui import QPixmap, Qt
import sysimport crop_rc  # 导入需要显示的画面# 定义需要显示的画面类
class MainWindow(QMainWindow, crop_rc.Ui_MainWindow):def __init__(self):super().__init__()# 系统的初始化
def start_todo():pass# #############################主程序##################################
if __name__ == '__main__':app = QApplication(sys.argv)# #######################项目级别的定义#############################class UI(QObject):  # 将项目定义为QObject,用来管理项目级别的信号和变量# ###########__init__###############def __init__(self):super().__init__()# ########################本项目的实例化############################ui = UI()  # 项目实例化# ########################实例化画面###############################window1 = MainWindow()  # 画面实例化window1.show()  # 显示画面window1.setupUi(window1)  # 画面初始化# ###########################信号的连接和槽函数###################### “保存文件”按钮点击的槽函数def window1_btn_save_clicked():pass# “保存文件”按钮点击的连接window1.btn_save.clicked.connect(window1_btn_save_clicked)# “恢复原图”按钮点击的槽函数def window1_btn_refresh_clicked():window1.label_show.set_src(ui.src_img)    # 设置并显示原始图像# “恢复原图”按钮点击的连接window1.btn_refresh.clicked.connect(window1_btn_refresh_clicked)# 几个信息显示标签的文字更新槽和连接def src_info_changed(txt):window1.src_info.setText(txt)def crop_info_changed(txt):window1.crop_info.setText(txt)def show_info_changed(txt):window1.show_info.setText(txt)window1.label_show.src_info.connect(src_info_changed)window1.label_show.crop_info.connect(crop_info_changed)window1.label_show.show_info.connect(show_info_changed)# ###########################系统的初始化#######################start_todo()ui.src_img = QPixmap('../PYS/9.png')  # 读取和定义原图像文件window1.label_show.set_src(ui.src_img)  # 设置并显示原图像sys.exit(app.exec())

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/27937.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis高并发高可用

1. 复制机制 在分布式系统中&#xff0c;为了解决单点问题&#xff0c;通常会将数据复制多个副本部署到其他机器&#xff0c;以满足故障恢复和负载均衡等需求。Redis提供了复制功能&#xff0c;实现了相同数据的多个Redis副本。复制功能是高可用Redis的基础&#xff0c;后面的…

长亭网络通信基础

长亭笔试之前就已经学过一遍了 这算温故而知新吧 TCP/IP 首先我在这里默写一下之前的7层和4层 应用层 应 【表示层 数据格式转换 传 【会话层 …

课设--学生成绩管理系统(一)

欢迎来到 Papicatch的博客 文章目录 &#x1f349;技术核心 &#x1f349;引言 &#x1f348;标识 &#x1f348;背景 &#x1f348;项目概述 &#x1f348; 文档概述 &#x1f349;可行性分析的前提 &#x1f348;项目的要求 &#x1f348;项目的目标 &#x1f348;…

Android 蓝牙配对Settings应用里面的简要流程记录

Android 蓝牙配对Settings应用里面的简要流程记录 文章目录 Android 蓝牙配对Settings应用里面的简要流程记录一、前言二、Settings蓝牙配对的关键代码1、接收蓝牙请求的地方 AndroidManifest.xml2、BluetoothPairingRequest3、BluetoothPairingService4、BluetoothPairingDial…

宿舍用电管理模块一进三出的升级改造

宿舍用电管理模块一进三出石家庄光大远通电气有限公司产品在高校日常管理工作中,宿舍管理是一项重要工作。宿舍管理内容复杂,而且涉及学生的日常生活,意义重大。其中,学生宿舍内漏电,超负荷用电,违规用电等现象一直是困扰后勤管理的普遍问题。随着学生日常生活方式以及生活用品…

驱动开发(五):Linux内核定时器

驱动开发系列文章&#xff1a; 驱动开发&#xff08;一&#xff09;&#xff1a;驱动代码的基本框架 驱动开发&#xff08;二&#xff09;&#xff1a;创建字符设备驱动 驱动开发&#xff08;三&#xff09;&#xff1a;内核层控制硬件层 驱动开发&#xff08;四&#xff…

移动端超超超详细知识点总结(Part4)

rem基础 1. rem单位 rem (root em)是一个相对单位&#xff0c;类似于em&#xff0c;em是父元素字体大小。不同的是rem的基准是相对于html元素的字体大小。比如&#xff0c;根元素&#xff08;html&#xff09;设置font-size12px; 非根元素设置width:2rem;则换成px表示就是24p…

数据防泄漏的六个步骤|数据防泄漏软件有哪些

在当前复杂多变的网络安全环境下&#xff0c;数据防泄漏软件成为了企业信息安全架构中不可或缺的一环。下面以安企神软件为例&#xff0c;告诉你怎么防止数据泄露&#xff0c;以及好用的防泄露软件。 1. 安企神软件 安企神软件是当前市场上备受推崇的企业级数据防泄漏解决方案…

【ARM-Linux篇】智能家居语音模块配置

1. pin脚配置&#xff1a; 2. 命令词自定义基本信息&#xff1a; 3. 命令词自定控制详情: • 测试&#xff1a;串口模块可先通过串口助手验证每个指令的准确性&#xff0c; 然后运行wiringOP中的serialTest程序(需把/dev/ttyS2改成/dev/ttyS5) 然后语音接收到指令后(比如喊你好…

10大wordpress外贸主题

手动工具wordpress外贸模板 适合生产套筒扳、管钳、工具箱、斧子、锤子、防爆工具、螺丝刀、扳手等手动工具的厂家。 https://www.jianzhanpress.com/?p4806 Invisible Trade WP外贸网站模板 WordPress Invisible Trade外贸网站模板&#xff0c;做进出口贸易公司官网的word…

开源高效API管理工具:RAP

RAP&#xff1a;简化API开发&#xff0c;提升团队协作效率- 精选真开源&#xff0c;释放新价值。 概览 RAP&#xff08;RESTful API Project&#xff09;是一个开源的API管理工具&#xff0c;由阿里巴巴团队开发并维护。它旨在帮助前后端开发人员通过一个统一的平台来设计、开…

软件方案评审与模块优化:从FOC模块出发的电控平台建设

一、背景 洞悉模块发展趋势&#xff0c;定制行业应用特点&#xff0c;明确优化方向与阶段性目标 随着科技进步的飞速发展&#xff0c;模块化设计已成为众多行业产品开发的核心理念。无论是软件系统、硬件组件&#xff0c;还是复杂系统中的功能模块&#xff0c;都需要对其发展…

如何提高软件质量

你写的程序是否有这些问题&#xff1a;命名不规范、函数设计不合理、分层不清晰、没有模块化概念、代码结构混乱、高度耦合等等。只是为了完成功能&#xff0c;从来没有考虑过代码质量问题、代码设计问题。 这样的代码维护起来非常费劲&#xff0c;添加或者修改一个功能&#…

Vue部分文件说明

1.eslintignore文件 Eslint会忽略的文件 # Eslint 会忽略的文件.DS_Store node_modules dist dist-ssr *.local .npmrc 2.gitignore # Git 会忽略的文件.DS_Store node_modules dist dist-ssr .eslintcache# Local env files *.local# Logs logs *.log npm-debug.log* yarn-de…

不可不知的Java SE技巧:如何使用for each循环遍历数组

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

HTML+CSS 旋转呼吸加载器

效果演示 实现了一个旋转加载动画效果&#xff0c;包括一个圆形的加载框和两个不同颜色的圆形旋转动画。加载框和动画都使用了CSS的动画属性&#xff0c;实现了旋转和缩放的效果。整个加载动画的样式比较简单&#xff0c;使用了黑色和黄色的背景色&#xff0c;以及白色的文本颜…

基于SVD的点云配准(下)

点云配准及特征提取详细解读 本篇博客将介绍一个用于点云配准的 C++ 代码示例,该示例使用 PCL(Point Cloud Library)库来处理和配准两个点云数据集。我们将逐步解析代码的关键部分,并解释每个步骤的作用。 代码说明 代码的整体结构及其主要功能: int main(int argc, ch…

【C++】【期末考】【基本概念和语法】概括总结——期末速成

目录 1. C简介 C的历史与发展 C的特点与优势 2. 基本语法 注释 数据类型与变量 常量 运算符 输入与输出 3. 控制结构 条件语句 循环语句 4. 函数 函数定义与声明 参数传递 返回值 函数重载 5. 数组与字符串 一维数组 多维数组 字符串处理 6. 指针 指针的…

本地部署 Stable Diffusion3

6月13日&#xff0c;Stability AI 正式开源20亿参数版本的Stable Diffusion 3 Medium。本文将在本地部署 SD3&#xff0c;GPU配置如下 GPU 2080TI / 22G 安装依赖 修改 WORKSPACE 位置信息&#xff0c;安装ComfyUI # #title Environment Setupfrom pathlib import PathOPTIO…

SoftReference 到底在什么时候被回收 ? 如何量化内存不足 ?

本文基于 OpenJDK17 进行讨论&#xff0c;垃圾回收器为 ZGC。 提示&#xff1a; 为了方便大家索引&#xff0c;特将在上篇文章 《以 ZGC 为例&#xff0c;谈一谈 JVM 是如何实现 Reference 语义的》 中讨论的众多主题独立出来。 大家在网上或者在其他讲解 JVM 的书籍中多多少少…