DearPyGui icon indicating copy to clipboard operation
DearPyGui copied to clipboard

Speed up loading of images by avoiding data transfer between DPG and Python

Open bandit-masked opened this issue 2 years ago • 2 comments

Following up on this question and a brief discussion with Cothren on Discord, Cothren suggested that the following potential reason for relatively slow loading of images to textures.

First, after loading the image data from file to DPG, the data (image_buffer?) is passed over from DPG to Python during load_image. And the second step is pass the data back from Python to DPG in order to load the texture.

        image_width, image_height, image_channels, image_buffer = dpg.load_image(file)
        texture = dpg.add_static_texture(image_width, image_height, image_buffer)
        dpg.draw_image(texture_tag=texture, pmin=(x_pos, y_pos), pmax=(x_pos + image_width, y_pos + image_height),
                       parent=layer)

In many cases, the combination of loading the file to the texture is what is required. In order to speed up that process, there should be a DPG function that combines both steps to avoid the data transfer from DPG to Python and back. Since there are static, dynamic and raw textures, this function would need an argument for the type of texture (or create three new functions, one for each texture type).

The function might look something like this.

texture = dpg.load_image_to_texture(filename, texture_type=static)

Or maybe instead of passing the image_buffer to Python, the image_buffer could be nothing more than a pointer and it would be faster already? Maybe it's just the checking of the correctness of the image_data that takes up most of the time...

bandit-masked avatar Jun 05 '22 19:06 bandit-masked

Thanks, @bandit-masked.

Yes, the step image_width, image_height, image_channels, image_buffer = dpg.load_image(file) is what I am seeing is taking the most time (0.1 seconds on average).

For my use case, the texture is already created, and the step of setting the image_buffer to the texture with dpg.set_value("example_texture", image_buffer) is quite fast compared to dpg.load_image.

It seems to me that the proposed solution would be faster yes, since the buffer wouldn't need to be sent back to Python after load_image is completed, though I do wonder if the majority of the time is taken by simply accessing the file system.

The solution that I previously attempted was to have a separate process handling the loading of the file, but I could not pass the buffer back to the DPG thread since the mvBuffer (image_buffer) isn't pickleable. I'm not sure what else to try in that vein.

Thanks for making this an issue!

keck-in-space avatar Jun 08 '22 20:06 keck-in-space

I did some profiling of the dpg.load_image call and found that it takes nearly a half second for some images. Here's the image I used. I renamed it to nasa.jpg.

image

keck-in-space avatar Jun 09 '22 19:06 keck-in-space