0
$\begingroup$

The forum member Blunder helped me a lot, but I still don't understand how to choose the right context and image buttons. I went through a lot of options from the documentation related to images and nothing fits.

I need to make an image panel with Image Browser, New+Open/Image name(if selected). For Node named "Sample". How can this be done using this code?

enter image description here

import bpy

class SelectImagePanel(bpy.types.Panel):
    """Creates a Panel in the World properties window"""
    bl_label = "World Image Panel"
    bl_idname = "OBJECT_PT_select_image"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "world"

    def draw(self, context):
        layout = self.layout

        **Context here?????**

        row = layout.row()
        row.label(text="Select an image", icon='WORLD_DATA')

        row = layout.row()
        row.prop(context.scene, 'select_image')


def register():
    bpy.utils.register_class(SelectImagePanel)
    bpy.types.Scene.select_image = bpy.props.PointerProperty(name='Image',type=bpy.types.Image)

def unregister():
    bpy.utils.unregister_class(HelloWorldPanel)


if __name__ == "__main__":
    register()
$\endgroup$

2 Answers 2

2
$\begingroup$

This is a simple example.

import bpy
from bpy_extras.io_utils import ExportHelper,ImportHelper
import os

class Select_PT_Image(bpy.types.Panel):
    """Creates a Panel in the World properties window"""
    bl_label = "World Image Panel"
    bl_idname = "OBJECT_PT_select_image"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "world"

    def draw(self, context):
        layout = self.layout
        
        if not context.scene.set_up_world == True:
            layout.operator('object.setup_world',icon='WORLD')
        else:    
            row = layout.row()
            row.label(text="Select an image", icon='WORLD_DATA')
            if context.scene.world.node_tree.nodes['SAMPLE']:
                row = layout.row(align=True)
                row.prop(context.scene.world.node_tree.nodes['SAMPLE'], 'image',icon_only = True)
                row = layout.row(align=True)
                row.operator('image.new_custom',text='New',icon='ADD')
                row.operator('image.open_custom',icon='FILE_FOLDER',text='Open')     
                
            
class Setup_OT_World(bpy.types.Operator):
    bl_label = "Setup World"
    bl_idname = "object.setup_world"
    
    def execute(self,context):
        context.scene.set_up_world = True
        w_tree = context.scene.world.node_tree
        w_image = w_tree.nodes.get('SAMPLE')
        if not w_image:
            w_image = w_tree.nodes.new('ShaderNodeTexImage')
            w_image.name = 'SAMPLE'
        w_bacground = w_tree.nodes['Background']
        w_tree.links.new(w_image.outputs[0],w_bacground.inputs[0])
        return {'FINISHED'}
    
class Simple_Open_OT_Operator(bpy.types.Operator,ImportHelper):
    bl_label = "Open Image"
    bl_idname = "image.open_custom"
    filter_glob: bpy.props.StringProperty(
        default="*.png;*.jpg")
    def execute(self,context):
        bpy.data.images.load(filepath=self.filepath)
        bpy.context.scene.world.node_tree.nodes['SAMPLE'].image = bpy.data.images[os.path.basename(self.filepath)]
        return {'FINISHED'}
    
class Simple_NEW_OT_Operator(bpy.types.Operator):
    bl_label = "New Image"
    bl_idname = "image.new_custom"
    
    name: bpy.props.StringProperty(name='Name',default='YourName')
    width: bpy.props.IntProperty(name='Width',default=1024)
    height: bpy.props.IntProperty(name='Height',default=1024)
    color: bpy.props.FloatVectorProperty(name='Color', subtype='COLOR')
    alpha: bpy.props.BoolProperty(name='Alpha',default=True)
    
    def execute(self,context):
        bpy.data.images.new(name=self.name,width=self.width, height=self.height, alpha=self.alpha)
        bpy.context.scene.world.node_tree.nodes['SAMPLE'].image = bpy.data.images[self.name]
        return {'FINISHED'}
    
    def invoke(self,context,event):
        return context.window_manager.invoke_props_dialog(self)

classes = [Select_PT_Image,Setup_OT_World,Simple_Open_OT_Operator,Simple_NEW_OT_Operator]

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.set_up_world = bpy.props.BoolProperty(name='Setup World')

def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)
    del bpy.types.Scene.set_up_world
    
if __name__ == "__main__":
    register()
```
$\endgroup$
1
  • $\begingroup$ Thank you! You wrote a very useful script, even a mini addon! $\endgroup$
    – M. Gordon
    Commented Dec 25, 2022 at 20:48
1
$\begingroup$

I have two examples of doing this. One is a pre-built Blender operator and another is a manual operator. I like to work with manual operators that's why I also created it for you.

Pre-built Operator Code:

import bpy

class SelectImagePanel(bpy.types.Panel):
    """Creates a Panel in the World properties window"""
    bl_label = "World Image Panel"
    bl_idname = "OBJECT_PT_select_image"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "world"

    def draw(self, context):
        layout = self.layout

#        **Context here?????**

        row = layout.row()
        row.label(text="Select an image", icon='WORLD_DATA')

        row = layout.row(align=True)
        row.prop(context.scene, 'select_image',icon='IMAGE_DATA')
        row.operator('image.new',text='New',icon='ADD')
        row.operator('image.open',icon='FILE_FOLDER',text='Open')
        
        
def register():
    bpy.utils.register_class(SelectImagePanel)
    bpy.types.Scene.select_image = bpy.props.PointerProperty(name='Image',type=bpy.types.Image)

def unregister():
    bpy.utils.unregister_class(HelloWorldPanel)


if __name__ == "__main__":
    register()

Manual Operator Code:

from bpy_extras.io_utils import ImportHelper
import os
class SelectImagePanel(bpy.types.Panel):
    """Creates a Panel in the World properties window"""
    bl_label = "World Image Panel"
    bl_idname = "OBJECT_PT_select_image"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "world"

    def draw(self, context):
        layout = self.layout

        row = layout.row()
        row.label(text="Select an image", icon='WORLD_DATA')

        row = layout.row(align=True)
        row.prop(context.scene, 'select_image',icon='IMAGE_DATA',icon_only=True)
        row.operator('image.new_custom',text='New',icon='ADD')
        row.operator('image.open_custom',icon='FILE_FOLDER',text='Open')
        
class Simple_Open_OT_Operator(bpy.types.Operator,ImportHelper):
    bl_label = "Open Image"
    bl_idname = "image.open_custom"
    filter_glob: bpy.props.StringProperty(
        default="*.png;*.jpg")
    def execute(self,context):
        bpy.data.images.load(filepath=self.filepath)
        bpy.context.scene.select_image = bpy.data.images[os.path.basename(self.filepath)]
        return {'FINISHED'}
    
class Simple_NEW_OT_Operator(bpy.types.Operator):
    bl_label = "New Image"
    bl_idname = "image.new_custom"
    
    name: bpy.props.StringProperty(name='Name',default='YourName')
    width: bpy.props.IntProperty(name='Width',default=1024)
    height: bpy.props.IntProperty(name='Height',default=1024)
    color: bpy.props.FloatVectorProperty(name='Color', subtype='COLOR')
    alpha: bpy.props.BoolProperty(name='Alpha',default=True)
    
    def execute(self,context):
        bpy.data.images.new(name=self.name,width=self.width, height=self.height, alpha=self.alpha)
        bpy.context.scene.select_image = bpy.data.images[self.name]
        return {'FINISHED'}
    
    def invoke(self,context,event):
        return context.window_manager.invoke_props_dialog(self)
def register():
    bpy.utils.register_class(SelectImagePanel)
    bpy.utils.register_class(Simple_Open_OT_Operator)
    bpy.utils.register_class(Simple_NEW_OT_Operator)
    bpy.types.Scene.select_image = bpy.props.PointerProperty(name='Image',type=bpy.types.Image)

def unregister():
    bpy.utils.unregister_class(HelloWorldPanel)
    bpy.utils.unregister_class(Simple_Open_OT_Operator)
    bpy.utils.unregister_class(Simple_NEW_OT_Operator)


if __name__ == "__main__":
    register()
```
$\endgroup$
1
  • $\begingroup$ Many thanks for the detailed answer! In this article, I asked the question how to make an Image Panel for a specific node, and I underlined it with a red line and write in question. That is, I need a link to the image options in node "Sample"(as far as I understand the code structure). I will be very grateful if you answer, @Muzammil $\endgroup$
    – M. Gordon
    Commented Dec 24, 2022 at 20:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .