Reputation:
I have a Raspberry Pi with an attached webcam and a python flask-script that sends out some informations as jsons and under the route /image.jpg an image.
In the past i capture the image to storage and served it from there but I feel it's more elegant (?) to only have it in memory.
I tried several iterations of something like this
class Repository( ):
def __init__( ... ):
self.temperature = None
...
self.image = None
...
self._config = {
...
"camera": picamera.PiCamera( ),
...
}
def initialize( self ):
...
self._create_image( )
...
def _create_image( self ):
self._config[ "camera" ].rotation = 180
self._config[ "camera" ].annotate_background = picamera.Color( 'black' )
self._config[ "camera" ].annotate_text = get_time_stamp( )
self._config[ "camera" ].annotate_text_size = 25
self._config[ "camera" ].flash_mode = 'auto'
# old way: self._config[ "camera" ].capture( '/app/public/' + "image.jpg", quality = 100 )
stream = BytesIO()
self._config[ "camera" ].start_preview()
sleep(2)
self._config[ "camera" ].capture( stream, quality = 100, format = 'jpeg' )
# "Rewind" the stream to the beginning, so we can read its content
stream.seek( 0 )
self.image = stream
and then serve it like this
@app.route( "/test/image.jpg" )
def return_image( ):
return send_file( data.image, mimetype = 'image/jpeg' )
I can see the image once (and since i have job that recalls _create_image every 60sec), every 1 minute. between that I get:
ValueError: I/O operation on closed file.
which makes sense, thinking that I needed to reverse the stream in the first place. So I tried something naive like this:
@app.route( "/test/image.jpg" )
def return_image_test( ):
test = data.image
data.image.seek( 0 )
return send_file( test, mimetype = 'image/jpeg' )
Well it seems like i am not understanding these streams and their nature of exhausting correctly. I bet the solution here is simple but I cannot wrap my head around it. obviously having something that I need to reverse every time also seems suboptimal. But I wasnt able to come up with a better way how flask could send out images.
please send help.
(in case that is important, i use waitress to serve this thing)
serve( app, host = "0.0.0.0", port = 80 )
Upvotes: 1
Views: 607
Reputation:
Ok,
all I had to do was
# save the read bytes instead of the stream
self.image = stream.read()
and returning it like this
@app.route( "/image.jpg" )
def return_image( ):
response = make_response( data.image )
response.headers.set( 'Content-Type', 'image/jpeg' )
return response
Upvotes: 1