[英]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.