如何在Dearpygui中显示GIF

问题描述 投票:0回答:1

由于 Dearpygui 本身不支持导入和显示 GIF,那么如何使用现有工具在 dpg 中渲染 GIF 并为其设置动画呢?

注意:问这个是为了我可以发布一个工作示例。

python animated-gif dearpygui
1个回答
0
投票

可以使用 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))
© www.soinside.com 2019 - 2024. All rights reserved.