Topic was automatically imported from the old Question2Answer platform.
Asked By
QuantumMartin
Hi, I try to create an image with float data in it (32bit Format.RF).
I have an array of float, I need to transform it in an array of bytes (PoolByteArray) to pass it as parameter of create_from_data() so I can create the image.
Here is what I did :
var byte_array:PoolByteArray
for i in range(layer_count):
var arr = []
for j in range(neuron_max):
if(j<weights[i].size()):
arr.append(weights[i][j]*255)
else:
arr.append(0)
byte_array.append_array(PoolByteArray(arr))
var wimg = Image.new()
wimg.create_from_data(neuron_max,layer_count,false, Image.FORMAT_RF, weights)
Error :
E 0:00:02.567 create: Expected data size of 108 bytes in Image::create(), got instead 3 bytes.
You created byte_array, but passed weights to create_from_data method. Shouldn’t it be wimg.create_from_data(neuron_max,layer_count,false, Image.FORMAT_RF, byte_array)?
Not sure if you still need an answer but I had to do something similar and couldn’t find anything helpful. Ended up with this:
var imageData: PoolByteArray
# Resize to required image size (* 4 as each float has 4 bytes)
imageData.resize(image_width * image_height * 4)
# Wrap 64-bit float into Vector2 to cast it to 32-bit
var valueVector: Vector2 = Vector2(value, 0.0)
# Convert Vector2 to bytes
var bytes: PoolByteArray = var2bytes(valueVector)
# Calculate position in image (* 4 as each float has 4 bytes)
var position: int = (y * image_width + x) * 4
# Read Vector.x float bytes (byte 4 to 7)
for i in range(4):
imageData[position + i] = bytes[i + 4]
var image: Image = Image.new()
image.create_from_data(image_width, image_height, false, Image.FORMAT_RF, imageData)
If you just append to the PoolByteArray this should work:
var valueVector: Vector2 = Vector2(value, 0.0)
var bytes: PoolByteArray = var2bytes(valueVector)
for i in range(4):
imageData.append(bytes[i + 4])
var image: Image = Image.new()
image.create_from_data(image_width, image_height, false, Image.FORMAT_RF, imageData)
Took me a while until I noticed that Godot uses 64-bit floats but the Images only support 32-bit floats.
There’s a useful class meant for building buffers to send over the network called StreamPeerBuffer, which can be used for this purpose.
var input = [ 0.1, 1.0, ... ]
var buffer := StreamPeerBuffer.new()
for value in input:
data.put_float(value) # Correctly serializes as 32-bit
var image := Image.new()
image.create_from_data(len(input), 1, false, Image.FORMAT_RF, buffer.data_array)