Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -65,11 +65,16 @@ def fourier_transform_drawing(input_image, frames, coefficients, img_size, blur_
|
|
| 65 |
draw_x, draw_y = [], []
|
| 66 |
theta = np.linspace(0, tau, theta_points)
|
| 67 |
coefs_static = [(np.linalg.norm(c), fr) for c, fr in coefs]
|
| 68 |
-
|
| 69 |
last_image = None
|
| 70 |
|
| 71 |
-
|
| 72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
center = (0, 0)
|
| 74 |
for idx, (r, fr) in enumerate(coefs_static):
|
| 75 |
c_dynamic = coefs[idx][0] * np.exp(1j * (fr * tau * time[i]))
|
|
@@ -77,25 +82,34 @@ def fourier_transform_drawing(input_image, frames, coefficients, img_size, blur_
|
|
| 77 |
circle_lines[idx].set_data([center[0], center[0] + np.real(c_dynamic)], [center[1], center[1] + np.imag(c_dynamic)])
|
| 78 |
circles[idx].set_data(x, y)
|
| 79 |
center = (center[0] + np.real(c_dynamic), center[1] + np.imag(c_dynamic))
|
| 80 |
-
|
| 81 |
draw_x.append(center[0])
|
| 82 |
draw_y.append(center[1])
|
| 83 |
drawing.set_data(draw_x[:i+1], draw_y[:i+1])
|
| 84 |
-
|
| 85 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
canvas = fig.canvas
|
| 87 |
-
canvas.draw()
|
| 88 |
w, h = canvas.get_width_height()
|
| 89 |
buf = np.frombuffer(canvas.buffer_rgba(), dtype=np.uint8)
|
| 90 |
image = Image.fromarray(buf.reshape(h, w, 4), 'RGBA').convert('RGB')
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
# Yield the current image and a placeholder for the final animation
|
| 94 |
-
yield (last_image, None)
|
| 95 |
|
| 96 |
# Generate and yield images for each frame
|
|
|
|
| 97 |
for frame in range(frames):
|
| 98 |
-
yield from animate(frame, coefs,
|
|
|
|
| 99 |
|
| 100 |
# Generate final animation
|
| 101 |
with tempfile.NamedTemporaryFile(delete=False, suffix='.mp4') as temp_file:
|
|
|
|
| 65 |
draw_x, draw_y = [], []
|
| 66 |
theta = np.linspace(0, tau, theta_points)
|
| 67 |
coefs_static = [(np.linalg.norm(c), fr) for c, fr in coefs]
|
|
|
|
| 68 |
last_image = None
|
| 69 |
|
| 70 |
+
# Initialize the background
|
| 71 |
+
fig.canvas.draw()
|
| 72 |
+
background = fig.canvas.copy_from_bbox(ax.bbox)
|
| 73 |
+
|
| 74 |
+
def animate(i, coefs, time, fig, ax, background, circles, circle_lines, drawing, draw_x, draw_y, coefs_static, theta):
|
| 75 |
+
# Restore the background to erase old frames
|
| 76 |
+
fig.canvas.restore_region(background)
|
| 77 |
+
|
| 78 |
center = (0, 0)
|
| 79 |
for idx, (r, fr) in enumerate(coefs_static):
|
| 80 |
c_dynamic = coefs[idx][0] * np.exp(1j * (fr * tau * time[i]))
|
|
|
|
| 82 |
circle_lines[idx].set_data([center[0], center[0] + np.real(c_dynamic)], [center[1], center[1] + np.imag(c_dynamic)])
|
| 83 |
circles[idx].set_data(x, y)
|
| 84 |
center = (center[0] + np.real(c_dynamic), center[1] + np.imag(c_dynamic))
|
| 85 |
+
|
| 86 |
draw_x.append(center[0])
|
| 87 |
draw_y.append(center[1])
|
| 88 |
drawing.set_data(draw_x[:i+1], draw_y[:i+1])
|
| 89 |
+
|
| 90 |
+
# Draw only the updated elements
|
| 91 |
+
for circle in circles:
|
| 92 |
+
ax.draw_artist(circle)
|
| 93 |
+
for line in circle_lines:
|
| 94 |
+
ax.draw_artist(line)
|
| 95 |
+
ax.draw_artist(drawing)
|
| 96 |
+
|
| 97 |
+
# Blit only the updated area
|
| 98 |
+
fig.canvas.blit(ax.bbox)
|
| 99 |
+
|
| 100 |
+
# Capture the current canvas state as a PIL Image
|
| 101 |
canvas = fig.canvas
|
|
|
|
| 102 |
w, h = canvas.get_width_height()
|
| 103 |
buf = np.frombuffer(canvas.buffer_rgba(), dtype=np.uint8)
|
| 104 |
image = Image.fromarray(buf.reshape(h, w, 4), 'RGBA').convert('RGB')
|
| 105 |
+
|
| 106 |
+
return (image, None)
|
|
|
|
|
|
|
| 107 |
|
| 108 |
# Generate and yield images for each frame
|
| 109 |
+
time = np.linspace(0, 1, num=frames)
|
| 110 |
for frame in range(frames):
|
| 111 |
+
yield from animate(frame, coefs, )
|
| 112 |
+
yield from animate(frame, coefs, time, fig, ax, background, circles, circle_lines, drawing, draw_x, draw_y, coefs_static, theta)
|
| 113 |
|
| 114 |
# Generate final animation
|
| 115 |
with tempfile.NamedTemporaryFile(delete=False, suffix='.mp4') as temp_file:
|