Serialize raw Image buffer (rgb pixels) in C and deserialize in Python

741 views Asked by At

I want to serialize raw image data i.e. uint16 array, and send it over to python using zmq. I am considered using msgPack-c but the only way I found was something like given How do I unpack and extract data properly using msgpack-c?.

if I follow this approach I have to pack each element in my C array separately, which will make it very slow.

Could someone please point to the right direction.

1

There are 1 answers

0
Grisha On

You can send uint16_t array from c side as is, and use ctypes module to access it in python code.

Sending c code:

#include <stdint.h>
#include <stdio.h>
#include <zmq.h>

#define IMAGE_SIZE (256 * 256)

unsigned checksum(uint16_t* data, int len) {
    unsigned s = 0;
    for (int i = 0; i < len; ++i) {
        s += data[i];
    }
    return s;
}

int main() {
    uint16_t image[IMAGE_SIZE];
    printf("image checksum: %i\n", checksum(image, IMAGE_SIZE));

    void* context = zmq_ctx_new();
    void* push = zmq_socket(context, ZMQ_PUSH);
    zmq_connect(push, "tcp://127.0.0.1:5555");
    zmq_send(push, image, IMAGE_SIZE * sizeof(uint16_t), 0);
    zmq_close(push);
    zmq_ctx_destroy(context);
    return 0;
}

Receiving python code:

from ctypes import c_uint16
import zmq

IMAGE_SIZE = 256 * 256
Image = c_uint16 * IMAGE_SIZE # corresponds to uint16_t[IMAGE_SIZE]

context = zmq.Context(1)
pull = zmq.Socket(context, zmq.PULL)
pull.bind("tcp://127.0.0.1:5555")
message = pull.recv()

image = Image.from_buffer_copy(message)

# This should print the same number as the sending code
# Note that it is different from sum(message)
print(sum(image))