热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

将图像平移到画布中心python_python–Tkinter画布缩放移动/平移

高级缩放示例.就像谷歌地图一样.它仅缩放图块,但不缩放整个图像.因此,缩放的瓷砖占据了恒定的记忆,并且不会为大型缩放图像调整大小的图像.对于简化的缩放示例lookhere.在Win

高级缩放示例.就像谷歌地图一样.

它仅缩放图块,但不缩放整个图像.因此,缩放的瓷砖占据了恒定的记忆,并且不会为大型缩放图像调整大小的图像.对于简化的缩放示例look here.

在Windows 7 64位和Python 3.6.2上测试.

不要忘记在脚本末尾放置图像路径.

# -*- coding: utf-8 -*-

# Advanced zoom example. Like in Google Maps.

# It zooms only a tile, but not the whole image. So the zoomed tile occupies

# constant memory and not crams it with a huge resized image for the large zooms.

import random

import tkinter as tk

from tkinter import ttk

from PIL import Image, ImageTk

class AutoScrollbar(ttk.Scrollbar):

''' A scrollbar that hides itself if it's not needed.

Works only if you use the grid geometry manager '''

def set(self, lo, hi):

if float(lo) <&#61; 0.0 and float(hi) >&#61; 1.0:

self.grid_remove()

else:

self.grid()

ttk.Scrollbar.set(self, lo, hi)

def pack(self, **kw):

raise tk.TclError(&#39;Cannot use pack with this widget&#39;)

def place(self, **kw):

raise tk.TclError(&#39;Cannot use place with this widget&#39;)

class Zoom_Advanced(ttk.Frame):

&#39;&#39;&#39; Advanced zoom of the image &#39;&#39;&#39;

def __init__(self, mainframe, path):

&#39;&#39;&#39; Initialize the main Frame &#39;&#39;&#39;

ttk.Frame.__init__(self, master&#61;mainframe)

self.master.title(&#39;Zoom with mouse wheel&#39;)

# Vertical and horizontal scrollbars for canvas

vbar &#61; AutoScrollbar(self.master, orient&#61;&#39;vertical&#39;)

hbar &#61; AutoScrollbar(self.master, orient&#61;&#39;horizontal&#39;)

vbar.grid(row&#61;0, column&#61;1, sticky&#61;&#39;ns&#39;)

hbar.grid(row&#61;1, column&#61;0, sticky&#61;&#39;we&#39;)

# Create canvas and put image on it

self.canvas &#61; tk.Canvas(self.master, highlightthickness&#61;0,

xscrollcommand&#61;hbar.set, yscrollcommand&#61;vbar.set)

self.canvas.grid(row&#61;0, column&#61;0, sticky&#61;&#39;nswe&#39;)

self.canvas.update() # wait till canvas is created

vbar.configure(command&#61;self.scroll_y) # bind scrollbars to the canvas

hbar.configure(command&#61;self.scroll_x)

# Make the canvas expandable

self.master.rowconfigure(0, weight&#61;1)

self.master.columnconfigure(0, weight&#61;1)

# Bind events to the Canvas

self.canvas.bind(&#39;&#39;, self.show_image) # canvas is resized

self.canvas.bind(&#39;&#39;, self.move_from)

self.canvas.bind(&#39;&#39;, self.move_to)

self.canvas.bind(&#39;&#39;, self.wheel) # with Windows and MacOS, but not Linux

self.canvas.bind(&#39;&#39;, self.wheel) # only with Linux, wheel scroll down

self.canvas.bind(&#39;&#39;, self.wheel) # only with Linux, wheel scroll up

self.image &#61; Image.open(path) # open image

self.width, self.height &#61; self.image.size

self.imscale &#61; 1.0 # scale for the canvaas image

self.delta &#61; 1.3 # zoom magnitude

# Put image into container rectangle and use it to set proper coordinates to the image

self.container &#61; self.canvas.create_rectangle(0, 0, self.width, self.height, width&#61;0)

# Plot some optional random rectangles for the test purposes

minsize, maxsize, number &#61; 5, 20, 10

for n in range(number):

x0 &#61; random.randint(0, self.width - maxsize)

y0 &#61; random.randint(0, self.height - maxsize)

x1 &#61; x0 &#43; random.randint(minsize, maxsize)

y1 &#61; y0 &#43; random.randint(minsize, maxsize)

color &#61; (&#39;red&#39;, &#39;orange&#39;, &#39;yellow&#39;, &#39;green&#39;, &#39;blue&#39;)[random.randint(0, 4)]

self.canvas.create_rectangle(x0, y0, x1, y1, fill&#61;color, activefill&#61;&#39;black&#39;)

self.show_image()

def scroll_y(self, *args, **kwargs):

&#39;&#39;&#39; Scroll canvas vertically and redraw the image &#39;&#39;&#39;

self.canvas.yview(*args, **kwargs) # scroll vertically

self.show_image() # redraw the image

def scroll_x(self, *args, **kwargs):

&#39;&#39;&#39; Scroll canvas horizontally and redraw the image &#39;&#39;&#39;

self.canvas.xview(*args, **kwargs) # scroll horizontally

self.show_image() # redraw the image

def move_from(self, event):

&#39;&#39;&#39; Remember previous coordinates for scrolling with the mouse &#39;&#39;&#39;

self.canvas.scan_mark(event.x, event.y)

def move_to(self, event):

&#39;&#39;&#39; Drag (move) canvas to the new position &#39;&#39;&#39;

self.canvas.scan_dragto(event.x, event.y, gain&#61;1)

self.show_image() # redraw the image

def wheel(self, event):

&#39;&#39;&#39; Zoom with mouse wheel &#39;&#39;&#39;

x &#61; self.canvas.canvasx(event.x)

y &#61; self.canvas.canvasy(event.y)

bbox &#61; self.canvas.bbox(self.container) # get image area

if bbox[0]

else: return # zoom only inside image area

scale &#61; 1.0

# Respond to Linux (event.num) or Windows (event.delta) wheel event

if event.num &#61;&#61; 5 or event.delta &#61;&#61; -120: # scroll down

i &#61; min(self.width, self.height)

if int(i * self.imscale) <30: return # image is less than 30 pixels

self.imscale /&#61; self.delta

scale /&#61; self.delta

if event.num &#61;&#61; 4 or event.delta &#61;&#61; 120: # scroll up

i &#61; min(self.canvas.winfo_width(), self.canvas.winfo_height())

if i

self.imscale *&#61; self.delta

scale *&#61; self.delta

self.canvas.scale(&#39;all&#39;, x, y, scale, scale) # rescale all canvas objects

self.show_image()

def show_image(self, event&#61;None):

&#39;&#39;&#39; Show image on the Canvas &#39;&#39;&#39;

bbox1 &#61; self.canvas.bbox(self.container) # get image area

# Remove 1 pixel shift at the sides of the bbox1

bbox1 &#61; (bbox1[0] &#43; 1, bbox1[1] &#43; 1, bbox1[2] - 1, bbox1[3] - 1)

bbox2 &#61; (self.canvas.canvasx(0), # get visible area of the canvas

self.canvas.canvasy(0),

self.canvas.canvasx(self.canvas.winfo_width()),

self.canvas.canvasy(self.canvas.winfo_height()))

bbox &#61; [min(bbox1[0], bbox2[0]), min(bbox1[1], bbox2[1]), # get scroll region box

max(bbox1[2], bbox2[2]), max(bbox1[3], bbox2[3])]

if bbox[0] &#61;&#61; bbox2[0] and bbox[2] &#61;&#61; bbox2[2]: # whole image in the visible area

bbox[0] &#61; bbox1[0]

bbox[2] &#61; bbox1[2]

if bbox[1] &#61;&#61; bbox2[1] and bbox[3] &#61;&#61; bbox2[3]: # whole image in the visible area

bbox[1] &#61; bbox1[1]

bbox[3] &#61; bbox1[3]

self.canvas.configure(scrollregion&#61;bbox) # set scroll region

x1 &#61; max(bbox2[0] - bbox1[0], 0) # get coordinates (x1,y1,x2,y2) of the image tile

y1 &#61; max(bbox2[1] - bbox1[1], 0)

x2 &#61; min(bbox2[2], bbox1[2]) - bbox1[0]

y2 &#61; min(bbox2[3], bbox1[3]) - bbox1[1]

if int(x2 - x1) > 0 and int(y2 - y1) > 0: # show image if it in the visible area

x &#61; min(int(x2 / self.imscale), self.width) # sometimes it is larger on 1 pixel...

y &#61; min(int(y2 / self.imscale), self.height) # ...and sometimes not

image &#61; self.image.crop((int(x1 / self.imscale), int(y1 / self.imscale), x, y))

imagetk &#61; ImageTk.PhotoImage(image.resize((int(x2 - x1), int(y2 - y1))))

imageid &#61; self.canvas.create_image(max(bbox2[0], bbox1[0]), max(bbox2[1], bbox1[1]),

anchor&#61;&#39;nw&#39;, image&#61;imagetk)

self.canvas.lower(imageid) # set image into background

self.canvas.imagetk &#61; imagetk # keep an extra reference to prevent garbage-collection

path &#61; &#39;doge.jpg&#39; # place path to your image here

root &#61; tk.Tk()

app &#61; Zoom_Advanced(root, path&#61;path)

root.mainloop()



推荐阅读
  • 本文详细介绍了Java中实现异步调用的多种方式,包括线程创建、Future接口、CompletableFuture类以及Spring框架的@Async注解。通过代码示例和深入解析,帮助读者理解并掌握这些技术。 ... [详细]
  • 本文深入探讨了UNIX/Linux系统中的进程间通信(IPC)机制,包括消息传递、同步和共享内存等。详细介绍了管道(Pipe)、有名管道(FIFO)、Posix和System V消息队列、互斥锁与条件变量、读写锁、信号量以及共享内存的使用方法和应用场景。 ... [详细]
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 深入理解 JMeter 定时器
    本文详细介绍了JMeter中定时器的功能和使用方法,探讨了其在性能测试中的重要性,并结合实际案例解释了如何合理配置定时器以模拟真实的用户行为。文章还涵盖了定时器的执行顺序及其与其他元件的相互作用。 ... [详细]
  • HDU 2871 内存管理问题(线段树优化)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2871。本题涉及内存管理操作,包括重置、申请、释放和查询内存块。通过使用线段树进行高效管理和维护。 ... [详细]
  • 本文详细介绍了Java库XChart中的XYSeries类下的setLineColor()方法,并提供了多个实际应用场景的代码示例。 ... [详细]
  • 本文探讨了如何通过一系列技术手段提升Spring Boot项目的并发处理能力,解决生产环境中因慢请求导致的系统性能下降问题。 ... [详细]
  • java文本编辑器,java文本编辑器设计思路
    java文本编辑器,java文本编辑器设计思路 ... [详细]
  • Logback使用小结
    1一定要使用slf4j的jar包,不要使用apachecommons的jar。否则滚动生成文件不生效,不滚动的时候却生效~~importorg.slf ... [详细]
  • 烤鸭|本文_Spring之Bean的生命周期详解
    烤鸭|本文_Spring之Bean的生命周期详解 ... [详细]
  • 本文详细解析了2019年西安邀请赛中的一道树形动态规划题目——J题《And And And》。题目要求计算树中所有子路径异或值为0的集合数量,通过深入分析和算法优化,提供了高效的解决方案。 ... [详细]
  • 本文详细介绍了Java中的注解功能,包括如何定义注解类型、设置注解的应用范围及生命周期,并通过具体示例展示了如何利用反射机制访问注解信息。 ... [详细]
  • 本文介绍了如何通过扩展 Panel 控件来实现滚动条位置的自动保存和恢复。类似于 Page 的 MaintainScrollPositionOnPostBack 属性,我们将在自定义的 TBPanel 控件中添加相同的功能。 ... [详细]
  • 本文将详细介绍NSRunLoop的工作原理,包括其基本概念、消息类型(事件源)、运行模式、生命周期管理以及嵌套运行等关键知识点,帮助开发者更好地理解和应用这一重要技术。 ... [详细]
  • 开发笔记:小程序分类页实现三级分类,顶部导航栏,左侧分类栏,右侧数据列表
    开发笔记:小程序分类页实现三级分类,顶部导航栏,左侧分类栏,右侧数据列表 ... [详细]
author-avatar
手机用户2502856895
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有