尝试使用tkinter动画一系列PIL图像。我的帧延迟图表(以毫秒为单位)看起来像这样:
![sawtooth frame duration](https://istack.dev59.com/LQXUw.webp)
有人知道是什么原因导致这种锯齿状的模式吗?
以下是用于复现的脚本:
from PIL import Image, ImageTk
import Tkinter
import time
import sys
def generate_frames(n):
"""
keep n under 101 * 101
"""
out = []
last_pil = None
for i in range(n):
if last_pil:
pil_image = last_pil.copy()
else:
pil_image = Image.new('L', (101, 101), 255)
x = i / 101
y = i % 101
pil_image.load()[x, y] = 0
out.append(ImageTk.PhotoImage(pil_image))
last_pil = pil_image
return out
def draw():
FRAME_COUNT =5000
master = Tkinter.Tk()
w = Tkinter.Canvas(master, width=302, height=302)
w.create_rectangle(49, 49, 252, 252)
w.pack()
frames = generate_frames(FRAME_COUNT)
def draw_frame(f, canvas_image):
print repr(time.time())
frame = frames[f]
if canvas_image is None:
canvas_image = w.create_image((151, 151), image=frame, anchor='center')
else:
w.itemconfigure(canvas_image, image=frame)
w.current_frame = frame # save a reference
next_frame = f + 1
if next_frame < FRAME_COUNT:
master.after(1, draw_frame, next_frame, canvas_image)
else:
sys.exit(0)
master.after(10, draw_frame, 0, None)
master.mainloop()
draw()
要查看图形,请通过管道输出
import sys
last = None
for line in sys.stdin:
value = float(line.strip()) * 1000
if last is None:
pass
else:
print (value - last)
last = value
然后通过
from matplotlib import pyplot
import sys
X = []
Y = []
for index, line in enumerate(sys.stdin):
line = line.strip()
X.append(index)
Y.append(float(line))
pyplot.plot(X, Y, '-')
pyplot.show()
多线程并不能改善这个问题:
class AnimationThread(threading.Thread):
FRAME_COUNT = 5000
def __init__(self, canvas):
threading.Thread.__init__(self)
self.canvas = canvas
self.frames = generate_frames(self.FRAME_COUNT)
def run(self):
w = self.canvas
frames = self.frames
canvas_image = None
for i in range(self.FRAME_COUNT):
print repr(time.time())
frame = frames[i]
if canvas_image is None:
canvas_image = w.create_image((151, 151), image=frame, anchor='center')
else:
w.itemconfigure(canvas_image, image=frame)
w.current_frame = frame
time.sleep(1 * .001)
def draw_threaded():
FRAME_COUNT = 5000
master = Tkinter.Tk()
w = Tkinter.Canvas(master, width=302, height=302)
w.create_rectangle(49, 49, 252, 252)
w.pack()
animation_thread = AnimationThread(w)
animation_thread.start()
master.mainloop()
animation_thread.join()
draw_threaded()
itemconfigure
与图像是缓慢的。例如,我将代码更改为删除并重新创建图像,在绘图中没有太多变化(尽管有人可能会正确地期望性能更差)。 - mmgpwx.glcanvas.GLCanvas
以高帧率绘制时遇到了类似的问题。你的显示适配器是否设置为垂直刷新同步? - ali_m