由于 Dearpygui 本身不支持导入和显示 GIF,那么如何使用现有工具在 dpg 中渲染 GIF 并为其设置动画呢?
注意:问这个是为了我可以发布一个工作示例。
可以使用 imageio 或 Pillow 将 GIF 的所有帧加载到内存中。从这里开始,技巧是使用
dpg.set_value
将加载到纹理中的帧更改为下一个 gif 帧,然后调用 dpg.render_dearpygui_frame()
将新帧渲染到窗口中。使用 time.sleep
,我们可以调整帧速率。
这里是一个用于加载、渲染和动画 GIF 的工作示例代码:
import dearpygui.dearpygui as dpg
import numpy as np
import imageio
import threading
import time
path_to_gif = "/path/to/your/gif/file.gif"
dpg.create_context()
dpg.create_viewport(title="Custom Title", width=600, height=800)
dpg.setup_dearpygui()
# Load the GIF using imageio
gif = imageio.mimread(path_to_gif)
# Function to adapt numpy image to dpg texture image
def adapt_frame_to_dpg(frame: np.ndarray) -> np.ndarray:
data = frame.ravel() # Flatten the data
data = np.asarray(data, dtype="float32") # Change data type to 32-bit floats
return np.true_divide(data, 255.0) # Normalize the image data
# Get the dimensions of the GIF
frame_width, frame_height = gif[0].shape[1], gif[0].shape[0]
frame = gif[0][:, :, :3] # Extract RGB channels
texture_data = adapt_frame_to_dpg(frame)
with dpg.texture_registry(show=False):
dpg.add_raw_texture(
frame_width,
frame_height,
texture_data,
tag="texture_tag",
format=dpg.mvFormat_Float_rgb,
)
with dpg.window(label="Animating a gif !"):
with dpg.drawlist(400, 265):
dpg.draw_image("texture_tag", (0, 0), (400, 265))
dpg.show_viewport()
frame_index = 0
# The animation function : Update the texture with the next frame of the GIF
def animate_gifs() -> None:
global frame_index, gif
desired_fps = 30
frame = gif[frame_index % len(gif)][:, :, :3] # Extract RGB channels
texture_data = adapt_frame_to_dpg(frame)
dpg.set_value("texture_tag", texture_data)
frame_index += 1
time.sleep(1 / desired_fps)
animation_thread = None
while dpg.is_dearpygui_running():
dpg.render_dearpygui_frame()
# Put the animation work in a thread to not slow the eventual inputs
if (
animation_thread != None
and not animation_thread.is_alive()
or animation_thread == None
):
animation_thread = threading.Thread(target=animate_gifs)
animation_thread.start()
dpg.destroy_context()
该代码也适用于视频,您只需要调整加载部分:
max_frames = 500 # Needed as imageio has a threshold on the amount of loadable data
video = imageio.get_reader(path_to_video)
gif = []
for f in range(min(max_frames, video.count_frames())):
gif.append(video.get_data(f))