Serialize 4 png Images into a Flatbuffer Array

19 views Asked by At

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.

0

There are 0 answers