创建圆形图像 PIL Tkinter

2024-05-09

Currently I have a zoom feature in my application that works very well, however I'd like the actual zoom box to be a circle instead. Here's what the current zoom looks like: enter image description here

放大的矩形是鼠标指针所在的位置,周围区域也被放大。但是我怎样才能使这个放大的对象成为圆形而不是方形呢?这是我的代码:

def zoom(self, event):
    if(event.delta > 0):
        if self.zoomValue != 4 : self.zoomValue += 1
    elif(event.delta < 0):
        if self.zoomValue != 0 : self.zoomValue -= 1
    self.crop(event)

def crop(self, event):
    if self.zimg_id: self.canvasLower.delete(self.zimg_id)
    if (self.zoomValue) != 0:
        x, y = event.x, event.y
        if self.zoomValue == 1:
            tmp = self.orig_img.crop((x-45, y-30, x+45, y+30))
        elif self.zoomValue == 2:
            tmp = self.orig_img.crop((x-30, y-20, x+30, y+20))
        elif self.zoomValue == 3:
            tmp = self.orig_img.crop((x-15, y-10, x+15, y+10))
        elif self.zoomValue == 4:
            tmp = self.orig_img.crop((x-6, y-4, x+6, y+4))
        size = 200, 200
        # crop tmp somehow to make the image a circle? maybe?
        self.zimg = ImageTk.PhotoImage(tmp.resize(size))
        self.zimg_id = self.canvasLower.create_image(event.x, event.y, image=self.zimg)

改编自这个答案 https://stackoverflow.com/a/890114/3714930(你需要ImageOps and ImageDraw进口自PIL),您可以使用以下方法为缩放图像创建圆形蒙版:

def create_mask(self):
    self.mask = Image.new('L', (200,200), 0)
    draw = ImageDraw.Draw(self.mask) 
    draw.ellipse((0, 0) + self.mask.size, fill=255)  

然后,你必须将面膜敷在你的身上crop功能:

output = ImageOps.fit(tmp, self.mask.size, centering=(0.5, 0.5))
output.putalpha(self.mask)
self.zimg = ImageTk.PhotoImage(output)

作为参考,一个完整的工作示例如下所示:

import Tkinter as tk
from PIL import Image, ImageTk, ImageOps, ImageDraw

class App():
    def __init__(self, master, image_path):
        self.orig_img = Image.open(image_path)
        self.tk_img  = ImageTk.PhotoImage(self.orig_img)

        w, h = self.orig_img.size
        self.canvas = tk.Canvas(master, width=w, height=h)
        self.canvas.pack()

        self.canvas.create_image(0, 0, image=self.tk_img, anchor='nw')
        self.canvas.bind_all("<MouseWheel>", self.zoom)
        self.canvas.bind_all("<Motion>", self.crop)

        self.create_mask()
        self.zoomValue = 0
        self.zimg_id = None

    def create_mask(self):
        self.mask = Image.new('L', (200,200), 0)
        draw = ImageDraw.Draw(self.mask) 
        draw.ellipse((0, 0) + self.mask.size, fill=255)        

    def zoom(self, event):
        if(event.delta > 0):
            if self.zoomValue != 4 : self.zoomValue += 1
        elif(event.delta < 0):
            if self.zoomValue != 0 : self.zoomValue -= 1
        self.crop(event)

    def crop(self, event):
        if self.zimg_id: self.canvas.delete(self.zimg_id)

        if (self.zoomValue) != 0:
            x, y = event.x, event.y
            if self.zoomValue == 1:
                tmp = self.orig_img.crop((x-45, y-30, x+45, y+30))
            elif self.zoomValue == 2:
                tmp = self.orig_img.crop((x-30, y-20, x+30, y+20))
            elif self.zoomValue == 3:
                tmp = self.orig_img.crop((x-15, y-10, x+15, y+10))
            elif self.zoomValue == 4:
                tmp = self.orig_img.crop((x-6, y-4, x+6, y+4))

            output = ImageOps.fit(tmp, self.mask.size, centering=(0.5, 0.5))
            output.putalpha(self.mask)
            self.zimg = ImageTk.PhotoImage(output)
            self.zimg_id = self.canvas.create_image(event.x, event.y, image=self.zimg)

root = tk.Tk()
App(root, r'C:\Users\user\Desktop\bg.gif')
root.mainloop()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建圆形图像 PIL Tkinter 的相关文章

  • 使用 python 进行串行数据记录

    Intro 我需要编写一个小程序来实时读取串行数据并将其写入文本文件 我在读取数据方面取得了一些进展 但尚未成功地将这些信息存储在新文件中 这是我的代码 from future import print function import se
  • 用于基于 MFC 的 GUI 应用程序的免费自动化测试工具

    我是 Windows 开发和测试平台的新手 我正在开发一个基于 MFC 的 GUI 应用程序 并正在寻找有助于 UI 自动化测试的工具 我搜索时出现了一大堆工具 但大多数似乎都不支持MFC 我考虑的选项是 A 编码 UI UI 自动化 看起
  • 如何正确地将 MIDI 刻度转换为毫秒?

    我正在尝试将 MIDI 刻度 增量时间转换为毫秒 并且已经找到了一些有用的资源 MIDI Delta 时间刻度到秒 http www lastrayofhope co uk 2009 12 23 midi delta time ticks
  • 如何迭代按值排序的 Python 字典?

    我有一本字典 比如 a 6 b 1 c 2 我想迭代一下by value 不是通过键 换句话说 b 1 c 2 a 6 最直接的方法是什么 sorted dictionary items key lambda x x 1 对于那些讨厌 la
  • 通过列表理解压平列表列表

    我正在尝试使用 python 中的列表理解来展平列表 我的清单有点像 1 2 3 4 5 6 7 8 只是为了打印这个列表列表中的单个项目 我编写了这个函数 def flat listoflist for item in listoflis
  • 将数据帧行转换为字典

    我有像下面的示例数据这样的数据帧 我正在尝试将数据帧中的一行转换为类似于下面所需输出的字典 但是当我使用 to dict 时 我得到了索引和列值 有谁知道如何将行转换为像所需输出那样的字典 任何提示都非常感激 Sample data pri
  • Pandas 中允许重复列

    我将一个大的 CSV 包含股票财务数据 文件分割成更小的块 CSV 文件的格式不同 像 Excel 数据透视表之类的东西 第一列的前几行包含一些标题 公司名称 ID 等在以下列中重复 因为一家公司有多个属性 而不是一家公司只有一栏 在前几行
  • 如何创建一个语句来打印以特定单词开头的单词? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 如何在 python 中打印从特定字母开始的单词 而不使用函数 而是使用方法或循环 1 我有一个字符串 想要打印以 m 开头的单词 S
  • 如何计算numpy数组中元素的频率?

    我有一个 3 D numpy 数组 其中包含重复的元素 counterTraj shape 13530 1 1 例如 counterTraj 包含这样的元素 我只显示了几个元素 array 136 129 130 103 102 101 我
  • 为什么Python的curses中escape键有延迟?

    In the Python curses module I have observed that there is a roughly 1 second delay between pressing the esc key and getc
  • 切片 Dataframe 时出现 KeyError

    我的代码如下所示 d pd read csv Collector Output csv df pd DataFrame data d dfa df copy dfa dfa rename columns OBJECTID Object ID
  • 以同步方式使用 FastAPI,如何获取 POST 请求的原始正文?

    在中使用 FastAPIsync not async模式 我希望能够接收 POST 请求的原始 未更改的正文 我能找到的所有例子都显示async代码 当我以正常同步方式尝试时 request body 显示为协程对象 当我通过发布一些内容来
  • 如何在 python 中没有 csv.reader 迭代器的情况下解析单行 csv 字符串?

    我有一个 CSV 文件 需要重新排列和重新编码 我想跑 line line decode windows 1250 encode utf 8 在由 CSV 读取器解析和分割之前的每一行 或者我想自己迭代行 运行重新编码 并仅使用单行解析表单
  • Qt 创建布局并动态添加小部件到布局

    我正在尝试在 MainWindow 类中动态创建布局 我有四个框架 它们是用网格布局对象放置的 每个框架都包含一个自定义的 ClockWidget 我希望 ClockWidget 对象在调整主窗口大小时相应地调整大小 因此我需要将它们添加到
  • 迭代 my_dict.keys() 并修改字典中的值是否会使迭代器失效?

    我的例子是这样的 for my key in my dict keys my dict my key mutate 上述代码的行为是否已定义 假设my dict是一本字典并且mutate是一个改变其对象的方法 我担心的是 改变字典中的值可能
  • tkinter - 检查文本小部件是否为空

    操作系统 Windows 8 1 Python 3 5 在 Tkinter 中 我发现了很多代码来验证输入框是否为空 但是当我尝试对文本小部件应用相同的方法时 它不起作用 看起来文本小部件有一个 n 字符 这可能就是问题所在 知道如何进行此
  • 优雅降级 - 何时考虑

    在为使用 AJAX 的应用程序设计和构建 UI 时 您何时考虑优雅降级 对于禁用 JavaScript 或正在使用屏幕阅读器的用户 最后 网站的 AJAX 版本完全完成后 在每个发展阶段 I don t 还有别的事 这些日子 渐进增强 ht
  • 在Python中按属性获取对象列表中的索引

    我有具有属性 id 的对象列表 我想找到具有特定 id 的对象的索引 我写了这样的东西 index 1 for i in range len my list if my list i id specific id index i break
  • 检查字典键是否有空值

    我有以下字典 dict1 city name yass region zipcode phone address tehsil planet mars 我正在尝试创建一个基于 dict1 的新字典 但是 它不会包含带有空字符串的键 它不会包
  • 列表值的意外更改

    这是我的课 class variable object def init self name name alias parents values table name of the variable self name 这是有问题的函数 f

随机推荐