Search code examples
numpyraspberry-pivideo-streamingstreamingmjpeg

Write numpy array to buffer as jpeg


I have a program which returns a stream of np.uin8 arrays. I would like to now broadcast these to a website being hosted by that computer.

I planned to do this by injecting the code in this documentation by replacing the line camera.start_recording(output, format='mjpeg') with output.write(<numpy_array_but_jpeg>). The documentation for start_recording states that if the write() method exists it will write the data in the requested format to that buffer. I can find lots of stuff online that instructs on how to save a np.uint8 as a jpeg, but in my case I want to write that data to a buffer in memory, and I won't want to have to save the image to file and then read that file into the buffer.

Unfortunately, changing the output format of the np.uint8 earlier in the stream is not an option.

Thanks for any assistance. For simplicity I have copied the important bits of code below

class StreamingOutput(object):
def __init__(self):
    self.frame = None
    self.buffer = io.BytesIO()
    self.condition = Condition()

def write(self, buf):
    if buf.startswith(b'\xff\xd8'):
        # New frame, copy the existing buffer's content and notify all
        # clients it's available
        self.buffer.truncate()
        with self.condition:
            self.frame = self.buffer.getvalue()
            self.condition.notify_all()
        self.buffer.seek(0)
    return self.buffer.write(buf)

with picamera.PiCamera(resolution='640x480', framerate=24) as camera:
    output = StreamingOutput()
    camera.start_recording(output, format='mjpeg')

Solution

  • OpenCV has functions to do this

    retval, buf = cv.imencode(ext,img[, params])

    lets you write an array to a memory buffer.

    This example here shows a basic implementation of what I was talking about.