2

I'm looking to open a new image editor window and display a new image from a file in it -- all via python script. What is the best way to do this? Searched but only found how to load and display an image, but not how to do it in a separate window. Thanks.

brockmann
  • 12,613
  • 4
  • 50
  • 93
chippwalters
  • 600
  • 3
  • 15
  • By separate window do you mean a floating window torn away from the rest of the program interface, or do you mean dividing an existing editor and changing to an image editor? Tear away can still be done by holding shift while pulling the top corner I believe. – Craig D Jones Apr 25 '20 at 04:32
  • floating window where you can view and save the image – chippwalters Apr 25 '20 at 05:09
  • Related: How do I get a popup UV Image Editor and force it to show the Active Paint Slot? Also, what did you find exactly? What exactly does not work? Please add that to your question and show some effort (just trying to help making this question better, according to How to ask a good question?...). – brockmann Apr 25 '20 at 08:49
  • Well, I already looked at the link you showed and realized it's not an image_editor with all the bells and whistles-- and I need to have the ability to save the image. I searched here and on BlendDev and on BA and Reddit and didn't find anything I could use.

    My take is it's not that easy to do, so I'll try and work around this. Turns out learning Python is the easy part-- learning the Blender API is much harder! haha

    – chippwalters Apr 25 '20 at 10:28
  • 2
    I'm getting an image editor in a seperate window from my old answer linked above (with all the bells and whistles). Isn't that what you want actually? In case you're rendering anything before you can just call bpy.ops.render.view_show("INVOKE_DEFAULT") to open up the render window. Please elaborate on your goal and add more information to your question. – brockmann Apr 25 '20 at 10:55

1 Answers1

5

Blender does not support creating a new window officially. However, there are some workarounds.

bpy.ops.screen.userpref_show()

One way is to open up a new User Preferences window and change its Area.type to 'IMAGE_EDITOR' using bpy.ops.screen.userpref_show() operator:

# Call user prefs window
bpy.ops.screen.userpref_show('INVOKE_DEFAULT')
# Change area type
area = bpy.context.window_manager.windows[-1].screen.areas[0]
area.type = 'IMAGE_EDITOR'

bpy.ops.screen.area_dupli()

Another way is using bpy.ops.screen.area_dupli(), which creates a new window from a specific area of your screen. Find an area of interest, store the Area.type, set it to 'IMAGE_EDITOR' call the the opeator and reset the area:

Blender 3.2+

import bpy
from bpy import context

Iterate through the areas

for area in context.screen.areas: if area.type in ('IMAGE_EDITOR', 'VIEW_3D', 'NODE_EDITOR'): old_area = area.type # Store current area type area.type = 'IMAGE_EDITOR' # Set the area to the Image editor with context.temp_override(area=area): # Override the area member bpy.ops.screen.area_dupli('INVOKE_DEFAULT') area.type = old_area # Restore the old area break

Blender 2.8+

# Copy context member
context = bpy.context.copy()

Iterate through the areas

for area in bpy.context.screen.areas: if area.type in ('IMAGE_EDITOR', 'VIEW_3D', 'NODE_EDITOR'): old_area = area.type # Store current area type area.type = 'IMAGE_EDITOR' # Set the area to the Image editor context['area'] = area # Override the area member bpy.ops.screen.area_dupli(context, 'INVOKE_DEFAULT') area.type = old_area # Restore the old area break

Assigning the image

In order to display an image in that window, just load an image and assign its data block it to SpaceImageEditor.image eg using the active space: bpy.context.area.spaces.active.image = image. Complete example using the code to generate an image from: Is it possible to create image data and save to a file from a script?:

enter image description here

size = 640, 480
image = bpy.data.images.new("MyImage", width=size[0], height=size[1])

pixels = [None] * size[0] * size[1] for x in range(size[0]): for y in range(size[1]): # assign RGBA to something useful r = x / size[0] g = y / size[1] b = (1 - r) * g a = 1.0

    pixels[(y * size[0]) + x] = [r, g, b, a]

pixels = [chan for px in pixels for chan in px] image.pixels = pixels

Call user prefs window

bpy.ops.screen.userpref_show('INVOKE_DEFAULT')

Change area type

area = bpy.context.window_manager.windows[-1].screen.areas[0] area.type = 'IMAGE_EDITOR'

Assign the image

bpy.context.area.spaces.active.image = image

Note: bpy.ops.render.view_show("INVOKE_DEFAULT") might be interesting as well.

p2or
  • 15,860
  • 10
  • 83
  • 143
brockmann
  • 12,613
  • 4
  • 50
  • 93