Detecting when the image in the Image Editor has been changed

Hi! How can I detect when the active Image in the Image Editor has been changed? With the following code, loading a new image fires a change to the depsgraph, but not when I switch the image.

def get_active_image():
    for area in bpy.context.screen.areas:
        if area.type == 'IMAGE_EDITOR':
            return area.spaces.active.image
 
@persistent
def depsgraph_update_post(scene, depsgraph):
    if not depsgraph.id_type_updated('IMAGE'):
        return

    print(get_active_image())

if __name__ == "__main__":
    bpy.app.handlers.depsgraph_update_post.append(depsgraph_update_post)

Unfortunately, if the depsgraph doesn’t register it, it’s not automatically detectable. Anything that is fires a depsgraph update. One potential workaround is to use a timer that checks the active image at intervals

1 Like

For something like this you should use the msgbus system:

import bpy

def msgbus_notify_image_changed():
    print("the image was changed!")
    
bpy.types.Scene.on_image_change = object()
bpy.msgbus.subscribe_rna(
    key=(bpy.types.SpaceImageEditor, 'image'),
    owner=bpy.types.Scene.on_image_change,
    args=(),
    notify=msgbus_notify_image_changed,
)

edit: when you unregister your addon, make sure you also clean up any msgbus subscriptions you made:

bpy.msgbus.clear_by_owner(bpy.types.Scene.on_image_change)
3 Likes

Incredible! Thank you very much @testure !