繁体   English   中英

如何在没有截图的情况下保存 tkinter window 的样子? (可能是 numpy 阵列?)

[英]How to save what a tkinter window looks like without screenshot? (Possibly a numpy array?)

我有一个简短的程序,可以生成 1、2、3 和 4 个随机彩色圆圈的图像来训练神经网络。 我的问题是,仅制作 4000 张图像大约需要 20-30 分钟,而我需要大约 50000 张图像。 我目前的方法是创建图像,对其进行截图,然后删除 tkinter object 并重新启动。 The issue is, windows 11 has a little fade in/slide animation when a new window is created, only about 200 ms, but it adds up quite a bit, because I need to wait for the animation to finish to take the screenshot.

所以我的问题是,除了屏幕截图,还有其他方法可以保存 tkinter canvas 吗?

我想指出的是,我将这些图像放入 numpy 数组中,因此可以选择将其直接放入数组中,但我需要某种方法将其保存为文件,因此我不需要每次都生成图像。

我当前的代码(仅显示我如何制作 4 个圆圈)

from PIL import ImageGrab
from tkinter import *
from random import choice, randint

colors = ["red", "blue", "green", "yellow", "orange", "purple", "black"]

s = 1   #scale 1 = 50x50 px canvas, 20x20 px circles

def four(i):
    def ss():
        x, y = screen.winfo_rootx(), screen.winfo_rooty()
        w, h = screen.winfo_width(), screen.winfo_height()
        img = ImageGrab.grab((x, y, x + w, y + h))
        img.save(f"4MC{i}.jpg")

    def des():
        root.destroy()
    
    root = Tk()

    screen = Canvas(root, width = 50 * s, height = 50 * s, bg="white")
    screen.pack()

    colors = ["red", "blue", "green", "yellow", "orange", "purple", "black"]

    x = randint(1 * s, 19 * s)
    y = randint(1 * s, 19 * s)

    screen.create_oval(x, y, x + 10 * s, y + 10 * s, fill=choice(colors), outline="")
    screen.create_oval(x, y + 20 * s, x + 10 * s, y + 30 * s, fill=choice(colors), outline="")
    screen.create_oval(x + 20 * s, y, x + 30 * s, y + 10 * s, fill=choice(colors), outline="")
    screen.create_oval(x + 20 * s, y + 20 * s, x + 30 * s, y + 30 * s, fill=choice(colors), outline="")

    root.after(200, ss)
    root.after(300, des)

    root.mainloop()

for i in range(1000):
    four(i)

我认为您在每次迭代中销毁和创建新 window 的方法是乏味的。 相反,您可以每次清除 canvas 并继续创建这个随机圆圈,然后单击它的图片。

from PIL import ImageGrab
from tkinter import *
from random import choice, randint

root = Tk()
colors = ["red", "blue", "green", "yellow", "orange", "purple", "black"]
s = 1 #scale 1 = 50x50 px canvas, 20x20 px circles
i = 1 # Variable for creating numbers in file-name: 1,2,3,...
LIMIT = 10 # Variable to keep limit of how many iterations/image

def create(i):
    if i <= LIMIT:
        screen.delete('all')
        
        x = randint(1 * s, 19 * s)
        y = randint(1 * s, 19 * s)

        screen.create_oval(x         , y         , x + 10 * s, y + 10 * s, fill=choice(colors), outline="")
        screen.create_oval(x         , y + 20 * s, x + 10 * s, y + 30 * s, fill=choice(colors), outline="")
        screen.create_oval(x + 20 * s, y         , x + 30 * s, y + 10 * s, fill=choice(colors), outline="")
        screen.create_oval(x + 20 * s, y + 20 * s, x + 30 * s, y + 30 * s, fill=choice(colors), outline="")
        
        if i == 1: # If it is first iteration, then the event loop hasnt been entered, so give a delay
            root.after(200, capture, screen, f'4MC{i}')
        else:
            # Give a general delay of 100ms before capturing the image
            root.after(100, capture, screen, f'4MC{i}')

        i += 1
        root.after(300, create, i) # Give a delay of 300ms before creating the circle

def capture(wid, file_name='img',file_format='png'):
    """Take screenshot of the passed widget"""
    
    x0 = wid.winfo_rootx()
    y0 = wid.winfo_rooty()
    x1 = x0 + wid.winfo_width()
    y1 = y0 + wid.winfo_height()
    
    im = ImageGrab.grab(bbox=(x0, y0, x1, y1)) # bbox means boundingbox, which is shown in the image below
    im.save(f'{file_name}.{file_format}')  # Can also say im.show() to display it

screen = Canvas(root, width = 50 * s, height = 50 * s, bg="white")
screen.pack()

create(i)

root.mainloop()

我用从我的另一个答案中获取的capture替换了您的ss ,逻辑相同但增加了更多灵活性,您可以使用 function 进行必要的更改。 我建议您首先使用LIMIT = 10运行它并检查延迟是否正常,如果不是,您可以调整它,然后继续生成 50000 图像集。

如果您还想将图像转换/加载为numpy数组,请查看下面的第一个参考链接。

额外参考:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM