Summary: TAPython has several methods for set pixels of RenderTexture2D and SImage, so we can edit the SImage widget or RenderTarget2D in the editor with python code.
and more...
The latest Version TAPython add several methods for set pixels of RenderTexture2D and SImage, so we can create some cool editor tools only with python.
[clouds video ][https://youtu.be/vlTsbGwdsvk]
The stable fluid simulation is powered by taichi-lang, which is an open-source, imperative, parallel programming language for high-performance numerical computation. It is embedded in Python and uses just-in-time (JIT) compiler frameworks, for example LLVM, to offload the compute-intensive Python code to the native GPU or CPU instructions.
Set pixels to SImage¶
set_image_data(...)
x.set_image_data(aka_name, raw_data, width, height, channel_num=4, bgr=True) -> None
Set SImage's Image content with Raw data.(R, G, B, Aļ¼uint8)
Args:
aka_name (Name): The aka name of the widget
raw_data (Array(uint8)): The flatten raw data of image, len(RawDataIn) == Height * Width * ChannelNum
width (int32): Width of Image.
height (int32): Height of Image.
channel_num (int32): Channel number of the RawData
bgr (bool):
- Fill white Replace the SImage with a new 1 pixel white Simage
your_chameleon_tool.data.set_image_data("imageInUI", b'\xff', 1, 1, 1, False)
- Fill red
The default order of channel is BGR, so the red color will be: b'\x00\x00\xff'
your_chameleon_tool.data.set_image_data("imageInUI", b'\x00\x00\xff'
, width=1
, height=1
, channel_num=3)
Set the parameter "bgr" to False if the channal order is RGB or RGBA
your_chameleon_tool.data.set_image_data("imageInUI", b'\xff\x00\x00'
, width=1
, height=1
, channel_num=3
, bgr=False)
- Fill Yellow but with translucent. The python logo is background image.
your_chameleon_tool.data.set_image_data("imageInUI", b'\xff\xff\x00\x80'
, width=1
, height=1
, channel_num=4
, bgr=False)
- Fill the RenderTarget with four pixels. The pixel order of the RawImage is Row First and the first pixel is in left corner.
raw_data = b'\xff\xff\xff' # white
raw_data += b'\x00\x00\x00' # black
raw_data += b'\xff\x00\x00' # red
raw_data += b'\x00\xff\x00' # green
chameleon_test.data.set_image_data("imageInUI"
, raw_data
, width=2
, height=2
, channel_num=3
, bgr=False)
so the four pixel SImage will be:
So blew code will generate a 128x128 SImage
import numpy as np
im = np.ones((256, 256, 3), dtype=np.uint8)
im[:128, :128, :] = (255, 255, 255)
im[:128, 128:, :] = (0, 0, 0)
im[:128, 128:, :] = (255, 0, 0)
im[128:, 128:, :] = (0, 255, 0)
image_bytes = im.data.tobytes()
chameleon_test.data.set_image_data("imageInUI"
, image_bytes
, 256, 256, 3
, bgr=False)
Set pixels to RenderTarget2D with python¶
TAPython also adds a new lib: PythonTextureLib. We can use it for editor texture and renderTarget.
unreal.PythonTextureLib.set_render_target_data()
set_render_target_data(...) method of builtins.type instance
X.set_render_target_data(render_target_texture, raw_data, raw_data_width, raw_data_height, raw_data_channel_num, use_srgb=False, texture_filter_value=-1, bgr=False) -> None
Set the RenderTexture2D By Raw Data.
note: The order of RawData is row first. Lower left corner is the first pixel, and upper right is the last
note: added in v1.0.7
Args:
render_target_texture (TextureRenderTarget2D): The target RenderTarget2D
raw_data (Array(uint8)): The flatten uint8 raw data of image, len(RawData) == RawDataWidth * RawDataHeight * RawDataChannelNum
raw_data_width (int32): The width of the RawData, we can fill the rt with smaller RawData
raw_data_height (int32): The Height of the RawData
raw_data_channel_num (int32): The Number of RawData's Channel. 1: grayscale; 2: grayscale with alpha; 3: rgb; 4 rgb with alpha
use_srgb (bool): Use SRGB or not
texture_filter_value (int32): The filter of texture: 0: Nearest, 1: Bilinear, 2: Trilinear, Use setting from the Texture Group.
bgr (bool): Is the order of RawData is Blue, Green, Red, otherwise RGB
Fill the RenderTarget with a solid color¶
The raw data size can be smaller then the target RenderTarget2D, so we can update the rt from python much easier and faster.
- Fill White
unreal.PythonTextureLib.set_render_target_data(your_rt
, raw_data=b'\xff'
, raw_data_width=1
, raw_data_height=1
, raw_data_channel_num=1)
- Fill Red, the channel order of RawData is RGB
unreal.PythonTextureLib.set_render_target_data(your_rt, b'\xff\x00\x00'
, raw_data_width=1
, raw_data_height=1
, raw_data_channel_num=3)
- Fill Yellow but with translucent, the channel order of RawData is RGBA
unreal.PythonTextureLib.set_render_target_data(your_rt
, raw_data=b'\xff\xff\x00\x80'
, raw_data_width=1
, raw_data_height=1
, raw_data_channel_num=4)
- Fill the RenderTarget with four pixels. The pixel order of the RawImage is Row First and from lower left corner, which is different with SImage.
raw_data = b'\xff\xff\xff' # white
raw_data += b'\x00\x00\x00' # black
raw_data += b'\xff\x00\x00' # red
raw_data += b'\x00\xff\x00' # green
unreal.PythonTextureLib.set_render_target_data(your_rt
, raw_data=raw_data
, raw_data_width=2
, raw_data_height=2
, raw_data_channel_num=3
, use_srgb=False)
- Fill the RenderTarget without any filter, will get a image with hard edge, just like below image.
raw_data = b'\xff\xff\xff\x00\x00\x00\xff\x00\x00\x00\xff\x00' # same data as example above
unreal.PythonTextureLib.set_render_target_data(syour_rt
, raw_data=raw_data
, raw_data_width=2
, raw_data_height=2
, raw_data_channel_num=3
, use_srgb=False
, texture_filter_value=0)
- Use the parameter:
bgr
if rawData order is BlueGreenRed
raw_data = b'\xff\xff\xff\x00\x00\x00\xff\x00\x00\x00\xff\x00'
unreal.PythonTextureLib.set_render_target_data(your_rt
, raw_data=raw_data
, raw_data_width=2
, raw_data_height=2
, raw_data_channel_num=3
, use_srgb=False
, texture_filter_value=0
, bgr=True)
- Generate the RawData with numpy, or get the RawData from other 3rd package taichigraphic
import numpy as np
im = np.ones((256, 256, 3), dtype=np.uint8)
for i in range(256):
im[i, :, 0] = i
image_bytes = im.data.tobytes()
unreal.PythonTextureLib.set_render_target_data(your_rt, image_bytes, 256, 256, 3
, use_srgb=False
, texture_filter_value=0)
- fill the RenderTarget with a checkerboard, the im's shape can be (height, width) without channel.
import numpy as np
width = height = 256
im = np.zeros((height, width), dtype=np.uint8)
for y in range(height):
for x in range(width):
im[y, x] = 255 if x % 2 == y % 2 else 0
unreal.PythonTextureLib.set_render_target_data(your_rt, im.data.tobytes(), width, height, 1
, use_srgb=False
, texture_filter_value=0)
Tips¶
- Use One channel RawData, if your just need a greyscale image
- Two channels RawData, will be a greyscale image with alpha channel.
Different Between Set pixels to SImage and RenderTarget2D¶
PythonTextureLib.set_render_target_data chameleon_data.set_image_data
Type | RawData's PixelOrder | RawData's Channel Order | bBGR Default value | Has Filter | |
---|---|---|---|---|---|
RT | Row first, Lower Left if the first pixel | RGB | False | Yes | |
SImage | Row first, Upper Left if the first pixel | BGR | True | No |
With ChameleonData.set_image_data and PythonTextureLib and set_render_target_data, we can edit both the image on the UI and the RenderTarget, and we can make the below tool possible.
The stable fluid simulation is powered by taichi-lang.
The Demo Unreal 5 project is here: