Tal
Tal

Reputation: 372

How do you serve a dynamically downloaded image to a browser using flask?

I'm working with an IP camera. I can use a URL such as this one to grab a static image off the camera:

http://Username:Password@IP_of_Camera:Port/streaming/channels/1/picture

What I want to do is have python/flask download the image from that URL when the client loads the page, and embed the image into the page using an img tag.

If I have a template that looks something like this:

<html>
    <head>
        <title>Test</title>
    </head>
    <body>
        <img src="{{ image }}">
    </body>
</html>

how do I replace the {{ image }} with the downloaded image?

Would I use urllib/requests to download the image to flask's static folder, replace {{ image }} with something like {{ url_for('static', filename="temp_image.png") }}, and then delete the image from the static folder when the page loads? Would I download it someplace else instead (other than the static folder)? Or is there some other way to do it that keeps the image in memory?

PS. I know it's possible to replace {{ image }} with that URL directly, but that reveals the username/password/IP/port of the camera to the client.

Upvotes: 0

Views: 3845

Answers (2)

Vasif
Vasif

Reputation: 1413

I would add a masking route on flask that fetches and serves the image directly. Lets say domain.com/image/user1/cam1

Your server would typically make a http request to the camera and once it receives a response, you can straight up serve it as a Response object with appropriate mimetype.

In this case, the image you fetched from camera resides in your RAM.

@app.route('image/<userID>/<camID>')
def fun(userID,camID):
    #  fetch the picture from appropriate cam
    pic = requests.get('http://'+
        'Username:Password'+ # dynamically replace user id / password/ auth
        '@IP_of_Camera:Port'+ #dynamically replace port / IP
        '/streaming/channels/1/picture')

    # do processing of pic here..

    return Response(pic,mimetype="image/png")

However, if this image needs to be served over and over again, then you might wanna cache it. In which case, I would pick something closer to your approach.

If you want to stream the camera images, it is a whole different ballgame.

Upvotes: 6

GMarsh
GMarsh

Reputation: 2501

import requests
url = "http://Username:Password@IP_of_Camera:Port/streaming/channels/1/picture"
response = requests.get(url)
if response.status_code == 200:
    f = open("/your/static/dir/temp.png", 'wb')
    f.write(response.content)
    f.close()

{{ url_for('static' filename="temp.png") }}

Not sure why you would need to delete it, but I guess you could if you thought that was required

Upvotes: 1

Related Questions