0 votes

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):

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.

Thank you for your precious help !

Godot version 3.3
in Engine by (12 points)

3 Answers

0 votes

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)?

by (1,650 points)
0 votes

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.

by (14 points)
0 votes

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)
ago by (14 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.