I have 4 png files that I want to serialize into a flatbuffer. I want to append each serialized png into an array and then send it to a host somewhere. The filenames and variable names are arbitrary. So let's say I have the four png images in a folder named "images". Let's just say the png files are named "image1.png, image2.png", etc. I wrote a schema for this:
namespace imageBuffer;
table image {
width: int;
height: int;
// Pixel Data as a Byte Array
pixelData: [ubyte];
}
root_type image;
The idea is that I want to put each png, in serialized form, into the "pixelData[]" array, and include the size of each image in the form of width and height. That way I can use those values later to possibly reshape the image(s). When running the flatc compiler for Python, I got the following generated header file:
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: imageBuffer
import flatbuffers
class image(object):
__slots__ = ['_tab']
@classmethod
def GetRootAsimage(cls, buf, offset):
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
x = image()
x.Init(buf, n + offset)
return x
# image
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
# image
def Width(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
return 0
# image
def Height(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
return 0
# image
def PixelData(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
a = self._tab.Vector(o)
return self._tab.Get(flatbuffers.number_types.Uint8Flags, a +
flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
return 0
# image
def PixelDataAsNumpy(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
return 0
# image
def PixelDataLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
return self._tab.VectorLen(o)
return 0
def imageStart(builder): builder.StartObject(3)
def imageAddWidth(builder, width): builder.PrependInt32Slot(0, width, 0)
def imageAddHeight(builder, height): builder.PrependInt32Slot(1, height, 0)
def imageAddPixelData(builder, pixelData): builder.PrependUOffsetTRelativeSlot(2,
flatbuffers.number_types.UOffsetTFlags.py_type(pixelData), 0)
def imageStartPixelDataVector(builder, numElems): return builder.StartVector(1, numElems, 1)
def imageEnd(builder): return builder.EndObject()
I have tried many different things. The latest serialization script I have is this:
import flatbuffers
# Generated flatc Header
import image
import os
def main():
image_list = []
folder = "images"
# Create a List to Hold the Vectors
pixel_data_vectors = []
for pic in os.listdir(folder):
if pic.endswith(".png") or pic.endswith(".jpg"):
path = os.path.join(folder, pic)
with open(path, 'rb') as file:
image_data = file.read()
image_list.append(image_data)
# Instantiate Flatbuffer Builder
builder = flatbuffers.Builder(1024)
# Create Vectors for the Serialized Image Data
for image_data in image_list:
pixel_data_vector = builder.CreateByteVector(image_data)
pixel_data_vectors.append(pixel_data_vector)
# Start the pixelData Vector
image.imageStartPixelDataVector(builder, len(pixel_data_vectors))
# Add Serialized Images to the pixelData Array
for data_vector in reversed(pixel_data_vectors):
builder.PrependUOffsetTRelative(data_vector)
# End the pixelData Vector
pixelData = builder.EndVector(len(pixel_data_vectors))
# Build the Image Flatbuffer
image.imageStart(builder)
image.imageAddWidth(builder, 1366)
image.imageAddHeight(builder, 768)
image.imageAddPixelData(builder, pixelData)
image_offset = image.imageEnd(builder)
builder.Finish(image_offset)
serialized_data = builder.Output()
# Write Flatbuffer to Binary File
binFile = "/home/root/serialized_images.bin"
with open(binFile, 'wb') as file:
file.write(serialized_data)
if __name__ == "__main__":
main()
I was able to, with a debug print statement, verify in a deserialization script that the integer values are in fact being displayed properly. The array, which is supposed to contain the serialized png files, doesn't seem to be displaying them properly. The goal is to eventually be able to deserialize each image back into png format, and then be an exact replica of the original png files. I am at a loss and any insight for properly serializing the png image files into a flatbuffer, or its array, will be appreciated!
My latest version of the deserialization script is:
# Generated flatc Header
import image
import matplotlib.pyplot as plt
# Extract Flatbuffer
binFile = "/home/root/serialized_images.bin"
with open(binFile, 'rb') as file:
serialized_data = file.read()
# Deserialize
fb = image.image.GetRootAsimage(serialized_data, 0)
# Access Members
width = fb.Width()
height = fb.Height()
#pixel_data = fb.PixelDataAsNumpy()
# Print the Two Integers
print("Image Width:", width)
print("Image Height:", height)
for i in range(4):
pixel_data_i = fb.PixelData(i)
print(f"PixelData[{i}]: {pixel_data_i}")
My idea was to verify what's in the deserialized array. I keep getting 4 integer values under 200, which doesn't seem right to me, but then again, I am a nube at using flatbuffers. Any help or insight would be appreciated.