4
$\begingroup$

is it possible to display an image within the blender UI interface ?

let say that i want to display a 500x500px image in the N panel in layout.box().column(), how to do that ?

blender can already do that when clicking on an enum with preview so it must be possible within the api right ? enter image description here

$\endgroup$
5
+50
$\begingroup$

Easy Way

Have you looked at template_preview

tex = bpy.data.textures['.hidden']
col = layout.box().column()
col.template_preview(tex)

Hard Way

So this works, but it requires a lot of finesse to make it usable. Not figured out yet how to create a layout of a fixed size to append to the panel layout for rendering over the top of. This code will render over the top of the properties panel, as opposed to the Panel UI element.

import bpy
import gpu
import bgl
from gpu_extras.batch import batch_for_shader

def draw():

    x1 = 0
    x2 = 200
    y1 = 0
    y2 = 200

    shader = gpu.shader.from_builtin('2D_IMAGE')
    batch = batch_for_shader(
        shader, 'TRI_FAN',
        {
            "pos": ((x1, y1), (x2, y1), (x2, y2), (x1, y2)),
            "texCoord": ((0, 0), (1, 0), (1, 1), (0, 1)),
        },
    )

    image = bpy.data.images['logo']

    if image.gl_load():
        return # an exception happened

    bgl.glActiveTexture(bgl.GL_TEXTURE0)
    bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode)
    shader.bind()
    shader.uniform_int("image", 0)
    batch.draw(shader)

    image.gl_free()

handler = bpy.types.SpaceProperties.draw_handler_add(draw,(),'WINDOW','POST_PIXEL')

# then remove the handler with ...
bpy.type.SpaceProperties.draw_handler_remove(handler, 'WINDOW')

The hard way is maybe not the best way

$\endgroup$
  • $\begingroup$ Thanks a lot for te answer. I’ll try this tonight :) is it possible to an image from an os folder ? I don’t like the fact that I will need to import all image of the folder into blender first to generate This image only in the ui. The user don’t need to see this data ? Maybe it’s possible to hide it ? $\endgroup$ – DB3D Oct 17 at 16:28
  • $\begingroup$ prefix the texture name with a . so that it is hidden $\endgroup$ – Moog Oct 17 at 17:52
  • $\begingroup$ wait it only works with textures list ? not images ? $\endgroup$ – DB3D Oct 18 at 11:24
  • $\begingroup$ There's also this docs.blender.org/api/blender2.8/bpy.utils.previews.html $\endgroup$ – Moog Oct 18 at 16:28
1
$\begingroup$

if the quality desired is not important this technique may work (icons) this script will display all the .jpg file of the directory folder in the n panel


import os
import bpy
import bpy.utils.previews

directory   = os.path.join(bpy.utils.user_resource('SCRIPTS'), "presets", "scatter_presets_custom\\")
list_raw = []

from os import listdir
from os.path import isfile, join
onlyfiles = [f for f in listdir(directory) if isfile(join(directory, f))]

for f in onlyfiles:
    if f[-4:] == ".jpg":
        list_raw.append(f)

class Panel(bpy.types.Panel):
    """Creates a Panel in the 3D view Tools panel"""
    bl_idname = "TEST_PT_Panel" 
    bl_label = "Scatter Icon test"
    bl_category = "Scatter BETA"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_context = "objectmode"

    def draw(self, context):
        global custom_icons

        for z in list_raw:
            self.layout.template_icon(icon_value=custom_icons[z[:-4]].icon_id,scale=10)

# global variable to store icons in
custom_icons = None

def register():
    global custom_icons
    custom_icons = bpy.utils.previews.new()

    for z in list_raw:
        custom_icons.load(z[:-4], os.path.join(directory, z), 'IMAGE')


    bpy.utils.register_class(Panel)

def unregister():
    global custom_icons
    bpy.utils.previews.remove(custom_icons)

    bpy.utils.unregister_class(Panel)

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.