Hey, were you successful with that in the meantime? I just started using the API and was looking for something similar.
The below code should work for 1 selected node. I left out all the safety checks for brevity.
I haven't tested the numpy part inside designer though, because I didn't install numpy into its python distribution, but I did check the conversions from the bytes to array in another python environment.
Basically I only used the ctypes.string_at function to read the buffer and converted using either uint8 or uint16, since the returned values can have different bits per channel (8/16).
from ctypes import string_at
import sd
from sd.api.sdproperty import SDPropertyCategory
from sd.api.sdvaluetexture import SDValueTexture
import numpy as np
def get_ui_manager():
ctx = sd.getContext()
app = ctx.getSDApplication()
ui_manager = app.getUIMgr()
return ui_manager
def get_sd_tex(node):
prop = node.getProperties(SDPropertyCategory.Output)[0] # Take the first output.
print(prop.getLabel())
value = node.getPropertyValue(prop)
sd_texture = SDValueTexture.get(value)
return sd_texture
def print_tex_info(sd_tex):
dim_x, dim_y = sd_tex.getSize()
print(f"Dimensions: {dim_x} x {dim_y}")
print(f"Bytes per pixel: {sd_tex.getBytesPerPixel()}")
address = sd_tex.getPixelBufferAddress()
print(f"Buffer Address: {address}")
def get_tex_bytes(sd_tex):
dim_x, dim_y = sd_tex.getSize()
address = sd_tex.getPixelBufferAddress()
tex_b = string_at(address, dim_x * dim_y * sd_tex.getBytesPerPixel())
return tex_b
def get_dtype(bpp):
if bpp in [1, 4]:
return np.uint8
else:
return np.uint16
def get_shape(sd_tex):
dim_x, dim_y = sd_tex.getSize()
if sd_tex.getBytesPerPixel() == 1:
return (dim_x, dim_y)
else:
return (dim_x, dim_y, 4)
def get_tex_array(sd_tex):
tex_b = get_tex_bytes(sd_tex)
dt = get_dtype(sd_tex.getBytesPerPixel())
shape = get_shape(sd_tex)
a = np.frombuffer(tex_b, dtype=dt).reshape(shape) # row x column (x rgba)
return a
if __name__ == '__main__':
ui_mgr = get_ui_manager()
node = ui_mgr.getCurrentGraphSelection()[0] # Assume we have 1 node of interest selected.
tex = get_sd_tex(node)
print_tex_info(tex)
img = get_tex_array(tex)