bgoldber
bgoldber

Reputation: 51

Combine a packed header and numpy array in Python

Does anybody have any tips on how to pack a header and then append it to some chunk of data?

For example, if I have a bit-packed header of 16 bytes, and then I want to append it to a raw RGB image of about 2MB, what is the most efficient way of doing this?

So far, I've tried the following

headerVals = ( str(headerVersion), str(formatEnum), frameCount, ntpTimestamp, width, height )
packedHdr = self.imgStruct.pack( *headerVals )

return packedHdr + data

However this fails with the following error because str and numpy arrays arent concat'able:

    return packedHdr + data
TypeError: cannot concatenate 'str' and 'numpy.ndarray' objects

The only way around this that I can think of, as a Python beginner, is the following which is extraordinarily slow for obvious reasons:

# Generate the header
headerVals = ( str(headerVersion), str(formatEnum), frameCount, ntpTimestamp, width, height )

packDir = 'cchqhh{0}h'.format(width*height*3)

return pack( packDir, str(headerVersion), str(formatEnum), frameCount, ntpTimestamp, width, height, *data )

Any ideas? As a Python initiate I find myself a little stumped by this!

UPDATE:

As per seth's suggestion below, I updated my code to the following, and it is working nicely.

# Generate the header
headerVals = ( str(headerVersion), str(formatEnum), frameCount, ntpTimestamp, width, height )
packedHdr = self.imgStruct.pack( *headerVals )

# Concatanate header to the data
return numpy.concatenate( ( numpy.fromstring( packedHdr, dtype=numpy.uint8 ), data ), axis=0 )

Upvotes: 0

Views: 770

Answers (2)

seth
seth

Reputation: 1788

Why not put headerVersion and formatEnum inside a numpy array, then try to concat?

Upvotes: 0

tiago
tiago

Reputation: 23492

To concatenate your header with the numpy array you'll need to have the array in binary form. Assuming data is an array of ints:

import struct

raw_data = packedHdr + struct.pack('i' * data.size, *data)

If your data is of a different kind, you need to specify it in st.pack. You can then unpack the resulting raw_data in the desired form.

Upvotes: 1

Related Questions