使用 Tkinter Canvas 小部件添加放大镜功能?

一、说明

        据我所知,内置的 Tkinter Canvas 类比例不会自动缩放图像。如果您无法使用自定义小部件,则可以缩放原始图像并在调用缩放函数时将其替换在画布上。

二、实现图像放大镜技术细节

        我如何将放大和缩小添加到以下脚本中,我想将其绑定到鼠标滚轮。如果您在 Linux 上测试此脚本,请不要忘记将 MouseWheel 事件更改为 Button-4 和 Button-5。

  1. 下面的代码片段可以合并到您的原始类中。它执行以下操作:缓存 Image.open() 的结果。
  2. 添加 redraw() 函数来计算缩放后的图像并将其添加到画布中,并且还会删除先前绘制的图像(如果有)。
  3. 使用鼠标坐标作为图像放置的一部分。我只是将 x 和 y 传递给 create_image 函数,以显示图像位置如何随着鼠标移动而移动。您可以将其替换为您自己的中心/偏移计算。
  4. 这使用 Linux 鼠标滚轮按钮 4 和 5(您需要将其推广到 Windows 等)。

三、代码实现

from tkinter import *
from PIL import Image,ImageTkclass LoadImage:def __init__(self,root):frame = Frame(root)self.canvas = Canvas(frame,width=900,height=900)self.canvas.pack()frame.pack()File = "d001.jpg"self.orig_img = Image.open(File)self.img = ImageTk.PhotoImage(self.orig_img)self.canvas.create_image(0,0,image=self.img, anchor="nw")self.zoomcycle = 0self.zimg_id = Noneroot.bind("<MouseWheel>",self.zoomer)self.canvas.bind("<Motion>",self.crop)def zoomer(self,event):if (event.delta > 0):if self.zoomcycle != 4: self.zoomcycle += 1elif (event.delta < 0):if self.zoomcycle != 0: self.zoomcycle -= 1self.crop(event)def crop(self,event):if self.zimg_id: self.canvas.delete(self.zimg_id)if (self.zoomcycle) != 0:x,y = event.x, event.yif self.zoomcycle == 1:tmp = self.orig_img.crop((x-45,y-30,x+45,y+30))elif self.zoomcycle == 2:tmp = self.orig_img.crop((x-30,y-20,x+30,y+20))elif self.zoomcycle == 3:tmp = self.orig_img.crop((x-15,y-10,x+15,y+10))elif self.zoomcycle == 4:tmp = self.orig_img.crop((x-6,y-4,x+6,y+4))size = 300,200self.zimg = ImageTk.PhotoImage(tmp.resize(size))self.zimg_id = self.canvas.create_image(event.x,event.y,image=self.zimg)if __name__ == '__main__':root = Tk()root.title("Crop Test")App = LoadImage(root)root.mainloop()

四、关于内存问题 

        更新我对不同的比例进行了一些测试,发现调整大小/创建图像使用了相当多的内存。我在配备 32GB RAM 的 Mac Pro 上使用 540x375 JPEG 进行了测试。以下是不同比例因子使用的内存:

 1x (500, 375) 14 M
2x (1000, 750) 19 M
4x (2000, 1500) 42 M
8x (4000, 3000) 181 M
16x (8000, 6000) 640 M
32x (16000, 12000) 1606 米
64x (32000, 24000) ...
        达到约 7400 M 并耗尽内存,_memcpy 中的 EXC_BAD_ACCESS
鉴于上述情况,更有效的解决方案可能是确定将显示图像的视口的大小,计算鼠标坐标中心周围的裁剪矩形,使用矩形裁剪图像,然后仅缩放裁剪部分。这应该使用常量内存来存储临时图像。否则,您可能需要使用第 3 方 Tkinter 控件来为您执行此裁剪/窗口缩放。

        更新 2 工作但过于简化的裁剪逻辑,只是为了让您开始:

 def redraw(self, x=0, y=0):if self.img_id: self.canvas.delete(self.img_id)iw, ih = self.orig_img.size# calculate crop rectcw, ch = iw / self.scale, ih / self.scaleif cw > iw or ch > ih:cw = iwch = ih# crop it_x = int(iw/2 - cw/2)_y = int(ih/2 - ch/2)tmp = self.orig_img.crop((_x, _y, _x + int(cw), _y + int(ch)))size = int(cw * self.scale), int(ch * self.scale)# drawself.img = ImageTk.PhotoImage(tmp.resize(size))self.img_id = self.canvas.create_image(x, y, image=self.img)gc.collect()

        只是为了其他发现这个问题的人的利益,我附上了我的最终测试代码,该代码使用画中画/放大镜缩放。它基本上只是对已经发布的样本偏差的更改。看到它也很酷:)。

        正如我之前所说,如果您在 Linux 上使用此脚本,请不要忘记将 MouseWheel 事件更改为 Button-4 和 Button-5。显然,您需要在显示“INSERT JPG FILE PATH”的位置插入 .JPG 路径。

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

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

相关文章

初阶数据结构-常见的排序算法

排序 排序的概念常见的排序算法常见排序算法的实现数组的打印 插入排序直接插入排序的实现希尔排序( 缩小增量排序 )希尔排序的实现 交换排序冒泡排序冒泡排序的实现选择排序选择排序的实现堆排序堆排序的实现快速排序快速排序非递归 归并排序归并排序的递归实现归并排序的非递…

Vue 3.0 使用的 diff 算法相比 Vue 2.0 中的双端比对有什么优势?

1、最长递增子序列算法 Vue 3.0 的 diff 算法采用了最长递增子序列算法&#xff0c;能够减少不必要的 DOM 操作&#xff0c;提升性能。 2、静态标记 Vue 3.0 中&#xff0c;编译器会对静态节点进行标记&#xff0c;在更新时可以直接跳过这些静态节点&#xff0c;减少 DOM 操作…

多个子div在父中垂直居中

在一个div下&#xff0c;有多个子div&#xff0c;且子div都是水平垂直居中 <template><div><div class"far"><!-- 注意需要多包裹一层 --><div><div class"son1">1</div><div class"son2">222…

MATLAB-文件自动批量读取文件,并按文件名称或时间顺序进行数据处理

我在处理文件数据时&#xff0c;发现一个一个文件处理效率太低&#xff0c;因此学习了下MATLAB中自动读取特定路径下文件信息的程序&#xff0c;并根据读取信息使用循环进行数据处理&#xff0c;提高效率&#xff0c;在此分享给大家这段代码并给予一些说明&#xff0c;希望能为…

Open3D 进阶(13)使用PCA将点云投影到主成分空间

目录 一、算法原理<font color="#dd00dd">1、三维点云投影二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。爬虫网站自重。 一、算法原理 1、三维点云投影 p r o j

IDEA初始配置

1. 详细设置 安装完IDEA之后的简单配置。 1.1 如何打开详细配置界面 1、显示工具栏 2、选择详细配置菜单或按钮 1.2 系统设置 1、默认启动项目配置 启动IDEA时&#xff0c;默认自动打开上次开发的项目&#xff1f;还是自己选择&#xff1f; 如果去掉Reopen projects on …

“Linux免除系统交互操作方法、expect自动化交互工具” 及 “SSH批量修改主机密码脚本”

一、Linux系统免除交互操作方法 1、EOF多文本输入 案例&#xff1a;为机器磁盘进行分区并实现挂载&#xff0c;免交互式操作&#xff0c;如何实现&#xff1f; #!/bin/bash fdisk /dev/sdb <<EOF n p 1 wq EOFmkfs.xfs /dev/sdb1 && mkdir -p /data &&am…

《动手学深度学习 Pytorch版》 8.6 循环神经网络的简洁实现

import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2lbatch_size, num_steps 32, 35 train_iter, vocab d2l.load_data_time_machine(batch_size, num_steps)8.6.1 定义模型 num_hiddens 256 rnn_layer nn.RNN(len(voca…

【python高级】设计模式、类工厂、对象工厂

一、说明 最近试着读Design pattern&#xff0c; 不过有些概念实在太抽象了&#xff0c; 整理一下自己所学抽象工厂的精神&#xff0c;就是要有abstract class&#xff08;not implement&#xff09;&#xff0c;而所有不同种类的对象&#xff0c;都是继承这个abstract class&a…

Linux命令(94)之history

linux命令之history 1.history介绍 linux命令history会记录并显示用户所执行过的所有命令&#xff0c;也可以对其命令进行修改和删除操作。 2.history用法 history [参数] history参数 参数说明-a将当前会话的历史信息追加到历史文件(.bash_history)中-c删除所有条目从而清…

【云计算网络安全】DDoS 攻击类型:什么是 ACK 洪水 DDoS 攻击

文章目录 一、什么是 ACK 洪水 DDoS 攻击&#xff1f;二、什么是数据包&#xff1f;三、什么是 ACK 数据包&#xff1f;四、ACK 洪水攻击如何工作&#xff1f;五、SYN ACK 洪水攻击如何工作&#xff1f;六、文末送书《AWD特训营》内容简介读者对象 一、什么是 ACK 洪水 DDoS 攻…

猫头虎博客带您使用Markdown编辑器

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

BAT026:删除当前目录及子目录下的空文件夹

引言&#xff1a;编写批处理程序&#xff0c;实现批量删除当前目录及子目录下的空文件夹。 一、新建Windows批处理文件 参考博客&#xff1a; CSDNhttps://mp.csdn.net/mp_blog/creation/editor/132137544 二、写入批处理代码 1.右键新建的批处理文件&#xff0c;点击【编辑…

代码随想录训练营二刷第五十八天 | 583. 两个字符串的删除操作 72. 编辑距离

代码随想录训练营二刷第五十八天 | 583. 两个字符串的删除操作 72. 编辑距离 一、583. 两个字符串的删除操作 题目链接&#xff1a;https://leetcode.cn/problems/delete-operation-for-two-strings/ 思路&#xff1a;定义dp[i][j]为要是得区间[0,i-1]和区间[0,j-1]所需要删除…

leetcode做题笔记179. 最大数

给定一组非负整数 nums&#xff0c;重新排列每个数的顺序&#xff08;每个数不可拆分&#xff09;使之组成一个最大的整数。 注意&#xff1a;输出结果可能非常大&#xff0c;所以你需要返回一个字符串而不是整数。 示例 1&#xff1a; 输入&#xff1a;nums [10,2] 输出&am…

Linux实现无需手动输入密码的自动化SSH身份验证

SSH密钥身份验证是一种安全的方式&#xff0c;使您能够在无需手动输入密码的情况下连接到远程服务器。以下是如何设置SSH密钥身份验证&#xff0c;以便您的脚本能够自动运行&#xff1a; 步骤 生成SSH密钥对: 在您的本地系统上生成SSH密钥对。如果您尚未生成&#xff0c;请使用…

JimuReport 积木报表 v1.6.4 稳定版本正式发布 — 开源免费的低代码报表

项目介绍 一款免费的数据可视化报表&#xff0c;含报表和大屏设计&#xff0c;像搭建积木一样在线设计报表&#xff01;功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等&#xff01; Web 版报表设计器&#xff0c;类似于excel操作风格&#xff0c;通过拖拽完成报…

【前端设计模式】之备忘录模式

备忘录模式是一种行为设计模式&#xff0c;它允许在不破坏封装性的前提下捕获和恢复对象的内部状态。在前端开发中&#xff0c;备忘录模式可以用于保存和恢复用户界面的状态&#xff0c;以及实现撤销和重做功能。 备忘录模式特性&#xff1a; 封装了对象的状态&#xff1a;备…

【微服务 SpringCloud】实用篇 · Eureka注册中心

微服务&#xff08;3&#xff09; 文章目录 微服务&#xff08;3&#xff09;1. Eureka的结构和作用2. 搭建eureka-server2.1 创建eureka-server服务2.2 引入eureka依赖2.3 编写启动类2.4 编写配置文件2.5 启动服务 3. 服务注册1&#xff09;引入依赖2&#xff09;配置文件3&am…

android 13.0 SystemUI导航栏添加虚拟按键功能(二)

1.概述 在13.0的系统产品开发中,对于在SystemUI的原生系统中默认只有三键导航,想添加其他虚拟按键就需要先在构建导航栏的相关布局 中分析结构,然后添加相关的图标xml就可以了,然后添加对应的点击事件,就可以了,接下来先分析第二步关于导航栏的相关布局情况 然后实现功能…