Streaming images with HttpResponse?

1,154 views
Skip to first unread message

Alex Karargyris

unread,
Nov 15, 2013, 11:15:21 AM11/15/13
to django...@googlegroups.com
I have this simple app that I opens webcam and processes the frames using OpenCV. In my views.py I have the following code:

    def processImage():
    
    while True:
        
        rval, frame = settings.CAP.read()  //Read frames from webcam
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)         //Make frame grayscale
        pil_img = Image.fromarray(gray)  
        
        response = HttpResponse(mimetype="image/png")
        pil_img.save(response, "PNG")
        
        return response

Although there is a while loop the function runs only once because it is broken by "return response". How could I change the code to make it run constantly?


Jorge Cardoso Leitão

unread,
Nov 15, 2013, 12:08:53 PM11/15/13
to django...@googlegroups.com
I Alex.

I believe that is not possible with Django views. Views are made for request-response, i.e. the client sends a request, the view returns a response, and that's it, end of connection.

In your case, the server has a stream of data that you want to constantly send to the client. This sounds like a standard problem for using Websockets.

Within Django, there are some apps for using Websockets, even though I don't know how websockets work well for video.

Hope this helps,
Jorge




--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/a13fe785-83ec-4a18-8377-090bdeda279d%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Javier Guerra Giraldez

unread,
Nov 15, 2013, 12:53:23 PM11/15/13
to django...@googlegroups.com
On Fri, Nov 15, 2013 at 12:08 PM, Jorge Cardoso Leitão
<jorgeca...@gmail.com> wrote:
> I believe that is not possible with Django views. Views are made for
> request-response, i.e. the client sends a request, the view returns a
> response, and that's it, end of connection.


i think the WSGI standard does support it, by setting a generator
instead of a string value as the response content.

the generator is a function that yield()s more content each time, so
the HTTP response becomes a stream of data.

but i think you're right that Django doesn't support it.

--
Javier

Tomas Ehrlich

unread,
Nov 15, 2013, 1:05:57 PM11/15/13
to django...@googlegroups.com
Hi there,
I don't know if it's relevant, I've never used it, but the name sounds promising:

StreamingHttpResponse
https://docs.djangoproject.com/en/dev/ref/request-response/#streaminghttpresponse-objects

Cheers,
Tom

Dne Fri, 15 Nov 2013 12:53:23 -0500
Javier Guerra Giraldez <jav...@guerrag.com> napsal(a):
signature.asc

Alex Karargyris

unread,
Nov 18, 2013, 10:33:57 AM11/18/13
to django...@googlegroups.com
Dear all,

Thank you for the help. I managed to setup StreamingHttpResponse to read the images from the media folder. However I believe that there is a syntax error with html code <img>. It doesn't display the image. Any help? I am attaching the code below.Thanks in advance!

def stream_response_generator():

    yield "<html><body>\n"

    for x in range(1, 10):

        rval, frame = settings.CAP.read()

        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        cv2.imwrite('media/image.jpeg', gray, [int(cv2.IMWRITE_JPEG_QUALITY), 90])

        time.sleep(.1)

        x={"src": "%s/image.jpeg" % (settings.MEDIA_URL), "alt": "Video Frame"}

        yield "<img %s/>" % x

    yield "</body></html>\n"


def camera(request):

    resp = StreamingHttpResponse(stream_response_generator())

    return resp

Alex Karargyris

unread,
Nov 18, 2013, 3:56:46 PM11/18/13
to django...@googlegroups.com
So thanks to Simon I was able to make this work. Here is the code for those who might be interested:

    yield "<html>"

    yield '<meta http-equiv="refresh" content="0.01" />'

    yield "<body>\n"

    rval, frame = settings.CAP.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    cv2.imwrite('media/image.jpeg', gray, [int(cv2.IMWRITE_JPEG_QUALITY), 90])

    x={"src""..%s/image.jpeg" % (settings.MEDIA_URL), "alt""Video Frame"}

    yield '<img src="%(src)s" alt="%(alt)s"/>' % x

    yield "</body></html>\n"


However as it doesn't stream the images but instead it saves and the html is refreshed every 0.01 secs. This does not seem to be an elegant solution because a) there is latency and b) the browser keeps reloading constantly. Some of you suggested websockets. Is there some good example for Django + Websockets for streaming images to the browser?

Thanks a lot!

-Alex


On Friday, November 15, 2013 11:15:21 AM UTC-5, Alex Karargyris wrote:

Brian Schott

unread,
Nov 18, 2013, 8:37:19 PM11/18/13
to django...@googlegroups.com, django...@googlegroups.com
What are you trying to do?  Typical approach would be to use Javascript to pull the images.  Take a look at dajaxice.  

Sent from Mailbox for iPhone


--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
Reply all
Reply to author
Forward
0 new messages