热门标签 | 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()



推荐阅读
  • 短视频app源码,Android开发底部滑出菜单首先依赖三方库implementationandroidx.appcompat:appcompat:1.2.0im ... [详细]
  • 本文介绍了 Android 开发中常用的滚动视图组件 ScrollView 和 HorizontalScrollView 的基本用法和注意事项,帮助开发者更好地处理屏幕内容超出显示范围的情况。 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • 本文通过具体示例探讨了如何在iOS应用中有效使用scrollView,并解决了常见的无法滚动问题。不仅介绍了基础的使用方法,还详细讲解了代码实现的具体步骤。 ... [详细]
  • 本文将深入探讨 Unreal Engine 4 (UE4) 中的距离场技术,包括其原理、实现细节以及在渲染中的应用。距离场技术在现代游戏引擎中用于提高光照和阴影的效果,尤其是在处理复杂几何形状时。文章将结合具体代码示例,帮助读者更好地理解和应用这一技术。 ... [详细]
  • Flutter 核心技术与混合开发模式深入解析
    本文深入探讨了 Flutter 的核心技术,特别是其混合开发模式,包括统一管理模式和三端分离模式,以及混合栈原理。通过对比不同模式的优缺点,帮助开发者选择最适合项目的混合开发策略。 ... [详细]
  • 管理UINavigationController中的手势返回 - Managing Swipe Back Gestures in UINavigationController
    本文介绍了如何在一个简单的闪存卡片应用中实现平滑的手势返回功能,以增强用户体验。 ... [详细]
  • 使用Echarts for Weixin 小程序实现中国地图及区域点击事件
    本文介绍了如何使用Echarts for Weixin在微信小程序中构建中国地图,并实现区域点击事件。包括效果展示、条件准备和逻辑实现的具体步骤。 ... [详细]
  • PBO(PixelBufferObject),将像素数据存储在显存中。优点:1、快速的像素数据传递,它采用了一种叫DMA(DirectM ... [详细]
  • 使用Tkinter构建51Ape无损音乐爬虫UI
    本文介绍了如何使用Python的内置模块Tkinter来构建一个简单的用户界面,用于爬取51Ape网站上的无损音乐百度云链接。虽然Tkinter入门相对简单,但在实际开发过程中由于文档不足可能会带来一些不便。 ... [详细]
  • 使用多项式拟合分析淘宝双11销售趋势
    根据天猫官方数据,2019年双11成交额达到2684亿元,再次刷新历史记录。本文通过多项式拟合方法,分析并预测未来几年的销售趋势。 ... [详细]
  • 装饰者模式(Decorator):一种灵活的对象结构设计模式
    装饰者模式(Decorator)是一种灵活的对象结构设计模式,旨在为单个对象动态地添加功能,而无需修改原有类的结构。通过封装对象并提供额外的行为,装饰者模式比传统的继承方式更加灵活和可扩展。例如,可以在运行时为特定对象添加边框或滚动条等特性,而不会影响其他对象。这种模式特别适用于需要在不同情况下动态组合功能的场景。 ... [详细]
  • 近日,我在处理一个复杂的前端问题时遇到了极大困扰。具体来说,我之前开发了一个功能丰富的纯jQuery代码的前端GridView控件,实现了多种功能和视觉效果,并在多个项目中表现良好。然而,最近在尝试应用 `border-box` 布局模式时,却遇到了意想不到的兼容性和性能问题。这提醒我们在条件尚未完全成熟的情况下,应谨慎使用 `border-box` 布局模式,以免引入不必要的复杂性和潜在的bug。 ... [详细]
  • 深入解析 Android 中 EditText 的 getLayoutParams 方法及其代码应用实例 ... [详细]
  • 本文详细介绍了使用 Python 进行 MySQL 和 Redis 数据库操作的实战技巧。首先,针对 MySQL 数据库,通过 `pymysql` 模块展示了如何连接和操作数据库,包括建立连接、执行查询和更新等常见操作。接着,文章深入探讨了 Redis 的基本命令和高级功能,如键值存储、列表操作和事务处理。此外,还提供了多个实际案例,帮助读者更好地理解和应用这些技术。 ... [详细]
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社区 版权所有