2013-08-23 8 views
5

Ich versuche zur Zeit etwas zu kodieren, die Webseiten meiner Webcam lassen anzuzeigen. Ich folge etwa das verknüpfte Tutorial auf this website, außer der Verwendung von Python und pygame statt Verarbeitung.Wie sende ich ein Pygame-Bild über Websockets?

Im Moment greift mein Code ein Pygame-Image (das ursprünglich ein SimpleCV-Bild war), versucht es in das jpg-Format zu konvertieren und sendet es über Websockets an den Client, wo es in einem img-Tag angezeigt wird. Ich kann jedoch nicht herausfinden, wie man ein Pygame-Bild in JPG umwandelt und es im Webbrowser korrekt anzeigt.

Dies ist mein Code für den Server, der Flasche und GEVENT verwendet:

#!/usr/bin/env python 

import base64 
import cStringIO 
import time 

from geventwebsocket.handler import WebSocketHandler 
from gevent.pywsgi import WSGIServer 
from flask import Flask, request, render_template 


import pygame 
pygame.init() 

import SimpleCV as scv 

app = Flask(__name__) 
cam = scv.Camera(0) 

@app.route('/') 
def index(): 
    return render_template('index.html') 

@app.route('/camera') 
def camera(): 

    if request.environ.get('wsgi.websocket'): 
     ws = request.environ['wsgi.websocket'] 

     while True:    
      image = cam.getImage().flipHorizontal().getPGSurface() 
      data = cStringIO.StringIO() 
      pygame.image.save(image, data) 
      ws.send(base64.b64encode(data.getvalue())) 
      time.sleep(0.5) 

if __name__ == '__main__': 
    http_server = WSGIServer(('',5000), app, handler_class=WebSocketHandler) 
    http_server.serve_forever() 

Das ist mein HTML-Datei:

<!DOCTYPE HTML> 
<html> 
<head> 
<title>Flask/Gevent WebSocket Test</title> 
    <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> 
    <script type="text/javascript" charset="utf-8"> 
     $(document).ready(function(){ 
      if ("WebSocket" in window) { 
       cam = new WebSocket("ws://" + document.domain + ":5000/camera"); 
       cam.onmessage = function (msg) { 
        $("#cam").attr('src', 'data:image/jpg;base64,' + msg.data); 
       }; 
       cam.onerror = function(e) { 
        console.log(e); 
       } 
      } else { 
       alert("WebSocket not supported"); 
      } 
     }); 
    </script> 
</head> 
<body> 
    <img id="cam" src="" width="640" height="480" /> 
</body> 
</html> 

Das sind die spezifischen Linien, die ich glaube, ich habe Probleme mit:

while True: 
    image = cam.getImage().flipHorizontal().getPGSurface() 
    data = cStringIO.StringIO() 
    pygame.image.save(image, data) 
    ws.send(base64.b64encode(data.getvalue())) 
    time.sleep(0.5) 

Derzeit wenn ich versuche, und mein Code ausführen, geht auf localhost:5000 Willen di spreize ein ungültiges JPG-Bild. Es wird auch wirklich lückig, wenn ich es in Firefox ausprobiere, aber das kann ein Problem sein, das nicht zusammenhängt, das ich später debuggen kann.

Ich habe überprüft und sichergestellt, dass das Bild pygame ein gültiges ist, da ich es aus einer anderen Bibliothek konvertiere, und auch überprüft, dass ich websockets korrekt verwendet, indem Sie Textdaten hin und her senden.

Ich habe auch versucht, pygame.image.to_string Aufruf zu versuchen und die pygame Oberfläche in RGB-Format zu konvertieren, aber das funktioniert auch nicht.

Was mache ich falsch?

+0

nicht mehr upvote Kann ... – leon

Antwort

4

das darunter liegende PIL Bild verwenden, können wir in einer Datei-ähnliches Objekt, zurückgelesen und Base-64 kodieren sie schreiben:

from geventwebsocket.handler import WebSocketHandler 
from gevent.pywsgi import WSGIServer 
from flask import Flask, request 
from time import sleep 
from cStringIO import StringIO 

import pygame 
pygame.init() 

import SimpleCV as scv 

app = Flask(__name__) 
cam = scv.Camera(0) 


@app.route('/camera') 
def camera(): 

    if request.environ.get('wsgi.websocket'): 
     ws = request.environ['wsgi.websocket'] 

     while True: 
      fp = StringIO() 
      image = cam.getImage().flipHorizontal().getPIL() 
      image.save(fp, 'JPEG') 
      ws.send(fp.getvalue().encode("base64")) 
      #fp.close() << benchmark and memory tests needed 
      sleep(0.5) 


if __name__ == '__main__': 
    http_server = WSGIServer(('',5000), app, handler_class=WebSocketHandler) 
    http_server.serve_forever() 
+0

Danke so sehr! Das hat perfekt funktioniert. – Michael0x2a

+0

Nahm mich 3 Stunden! Faktor in der immer einfachen Workstation-Setup auf einem Mac und völliger Mangel an Wissen über die Bildbibliotheken :) – leon

Verwandte Themen