From e1d541a6e4ffedcea9fdeaf2a0a64f6e439c09ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Wed, 2 Jan 2013 16:33:37 +0100 Subject: [PATCH] First try at webcam support --- printer_webui/server.py | 22 +++++++++++++- printer_webui/static/css/ui.css | 13 ++++++++ printer_webui/static/js/ui.js | 29 ++++++++++++++++++ printer_webui/templates/index.html | 8 ++++- printer_webui/webcam.py | 49 ++++++++++++++++++++++++++++++ 5 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 printer_webui/webcam.py diff --git a/printer_webui/server.py b/printer_webui/server.py index c746e206..242e9a13 100644 --- a/printer_webui/server.py +++ b/printer_webui/server.py @@ -2,11 +2,12 @@ __author__ = "Gina Häußge " __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' -from flask import Flask, request, render_template, jsonify, make_response +from flask import Flask, request, render_template, jsonify, send_from_directory, abort from werkzeug import secure_filename from printer_webui.printer import Printer, getConnectionOptions from printer_webui.settings import settings +from printer_webui.webcam import hasWebcamSupport, Webcam import sys import os @@ -20,8 +21,16 @@ if not os.path.isdir(UPLOAD_FOLDER): os.makedirs(UPLOAD_FOLDER) ALLOWED_EXTENSIONS = set(["gcode"]) +WEBCAM_FOLDER = os.path.join(settings().settings_dir, "webcam") +if not os.path.isdir(WEBCAM_FOLDER): + os.makedirs(WEBCAM_FOLDER) + app = Flask("printer_webui") printer = Printer() +if hasWebcamSupport(): + webcam = Webcam() +else: + webcam = None @app.route("/") def index(): @@ -251,6 +260,17 @@ def setSettings(): s.save() return getSettings() +#~~ webcam + +@app.route(BASEURL + "webcam/image", methods=["GET"]) +def getImage(): + if webcam is None: + abort(404) + + filename = "current.jpg" + webcam.save(os.path.join(WEBCAM_FOLDER, filename)) + return send_from_directory(WEBCAM_FOLDER, filename) + #~~ helper functions def sizeof_fmt(num): diff --git a/printer_webui/static/css/ui.css b/printer_webui/static/css/ui.css index 3e9240f2..b2088360 100644 --- a/printer_webui/static/css/ui.css +++ b/printer_webui/static/css/ui.css @@ -93,3 +93,16 @@ table th.gcode_files_action, table td.gcode_files_action { #offline_overlay_wrapper .container { margin: auto; } + +#webcam_container { + height: 440px; + background-color: #000000; +} + +#webcam_placeholder { + height: 440px; + line-height: 440px; + text-align: center; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} \ No newline at end of file diff --git a/printer_webui/static/js/ui.js b/printer_webui/static/js/ui.js index 02cd6a85..a30a86b1 100644 --- a/printer_webui/static/js/ui.js +++ b/printer_webui/static/js/ui.js @@ -1,3 +1,5 @@ +//~~ View models + function ConnectionViewModel() { var self = this; @@ -436,6 +438,32 @@ function DataUpdater(connectionViewModel, printerStateViewModel, temperatureView } var dataUpdater = new DataUpdater(connectionViewModel, printerStateViewModel, temperatureViewModel, speedViewModel, terminalViewModel); +function WebcamViewModel() { + var self = this; + + self.webcamUpdateInterval = 5000; + self.offlineUrl = "/static/img/webcam-offline.png"; + + self.url = ko.observable(undefined); + self.enabled = ko.observable(undefined); + + self.enabled.subscribe(function(newValue) { + if (newValue) { + self.requestData(); + } else { + $("#webcam_image") + } + }); + + self.requestData = function() { + if (!self.enabled()) + return; + self.url(AJAX_BASEURL + "webcam/image?" + (new Date()).getTime()); + setTimeout(self.requestData, self.webcamUpdateInterval); + } +} +var webcamViewModel = new WebcamViewModel(); + $(function() { //~~ Print job control @@ -575,6 +603,7 @@ $(function() { ko.applyBindings(printerStateViewModel, document.getElementById("jog")); ko.applyBindings(terminalViewModel, document.getElementById("term")); ko.applyBindings(speedViewModel, document.getElementById("speed")); + ko.applyBindings(webcamViewModel, document.getElementById("webcam")); //~~ startup commands diff --git a/printer_webui/templates/index.html b/printer_webui/templates/index.html index 465c970b..5248a813 100644 --- a/printer_webui/templates/index.html +++ b/printer_webui/templates/index.html @@ -217,7 +217,13 @@
- Here be webcam stuff + +
+ +
Offline
+
diff --git a/printer_webui/webcam.py b/printer_webui/webcam.py new file mode 100644 index 00000000..668b405f --- /dev/null +++ b/printer_webui/webcam.py @@ -0,0 +1,49 @@ +# coding=utf-8 +__author__ = "Gina Häußge " +__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' + +try: + #Try to find the OpenCV library for video capture. + from opencv import cv + from opencv import highgui +except: + cv = None + +try: + import VideoCapture as win32vidcap +except: + win32vidcap = None + +def hasWebcamSupport(): + if cv == None and win32vidcap == None: + return False + return True + +class Webcam(object): + def __init__(self): + self._cam = None + if cv != None: + self._cam = highgui.cvCreateCameraCapture(-1) + elif win32vidcap != None: + try: + self._cam = win32vidcap.Device() + self._cam.setResolution(640, 480) + except: + pass + + def save(self, filename): + if self._cam is None: + return + + if cv is not None: + frame = cv.QueryFrame(self._cam) + cv.SaveImage(filename, frame) + elif win32vidcap is not None: + self._cam.saveSnapshot(filename) + +if __name__ == "__main__": + from printer_webui.settings import settings + import os + + webcam = Webcam() + webcam.save(os.path.join(settings().settings_dir, "image.png")) \ No newline at end of file