#!/usr/bin/python2.4 ## -*- coding: utf-8 -*- # Copyright (c) 2006 INdT - Instituto Nokia de Tecnologia, Elvis Pfutzenreuter. # All rights reserved. This software is released under the LGPL licence. import gtk import pygst import gst import time import Image WIDTH, HEIGHT = 640, 480 EFFECTS = [ ("quarktv",), ("postproc_lowpass5",), ("revtv",), ("vertigotv",), ("shagadelictv",), ("warptv",), ("dicetv",), ("agingtv",), ("edgetv",), ("videobalance", {"saturation": 0.5, "hue": -0.5}), ("videobalance", {"saturation": 0.5, "hue": 0}), ("videobalance", {"saturation": 0.5, "hue": +0.5}), ("videobalance", {"saturation": 1.5, "hue": -0.5}), ("videobalance", {"saturation": 1.5, "hue": 0}), ("videobalance", {"saturation": 1.5, "hue": +0.5}), ("videobalance", {"saturation": 0, "contrast": 0.5}), ("videobalance", {"saturation": 0, "contrast": 2}), ("videobalance", {"saturation": 0.5, "contrast": 2}), ("videobalance", {"saturation": 1, "contrast": 2}), ("videobalance", {"saturation": 2, "contrast": 2}), ("videobalance", {"saturation": 0}), ] class PhotoboothEngine: def __init__(self): self.pipeline = gst.Pipeline("photobooth") self.do_grab_frame = False self.xwindow = 0 # Alternate sources to run outside of Internet Tablet #source = gst.element_factory_make("videotestsrc", "src") #source.set_property("is-live", True) source = gst.element_factory_make("gconfvideosrc", "src") self.pipeline.add(source) self.csp1 = gst.element_factory_make("ffmpegcolorspace", "csp1") self.pipeline.add(self.csp1) self.effect = gst.element_factory_make(EFFECTS[0][0], "effect") self.pipeline.add(self.effect) self.csp2 = gst.element_factory_make("ffmpegcolorspace", "csp2") self.pipeline.add(self.csp2) caps1 = gst.element_factory_make("capsfilter", "caps1") self.pipeline.add(caps1) tee = gst.element_factory_make("tee", "tee") self.pipeline.add(tee) queuevid = gst.element_factory_make("queue", "queuevid") self.pipeline.add(queuevid) csp3 = gst.element_factory_make("ffmpegcolorspace", "csp3") self.pipeline.add(csp3) self.sink = gst.element_factory_make("xvimagesink", "sink") self.pipeline.add(self.sink) queueimg = gst.element_factory_make("queue", "queueimg") self.pipeline.add(queueimg) fakesink = gst.element_factory_make("fakesink", "fakesink") self.pipeline.add(fakesink) fakesink.set_property("signal-handoffs", True) fakesink.connect("handoff", self.on_buffer) caps1.set_property('caps', gst.caps_from_string("video/x-raw-rgb,width=%d,height=%d,bpp=24,depth=24,framerate=30/1" % (WIDTH, HEIGHT))) source.link(self.csp1) self.csp1.link(self.effect) self.effect.link(self.csp2) self.csp2.link(caps1) caps1.link(tee) tee.link(queuevid) queuevid.link(csp3) csp3.link(self.sink) tee.link(queueimg) queueimg.link(fakesink) def on_buffer(self, element, buffer, pad): if self.do_grab_frame: self.save_image(buffer) self.do_grab_frame = False return True def save_image(self, buffer): img = Image.frombuffer("RGB", (WIDTH, HEIGHT), buffer, 'raw', 'RGB', 0, 1) img.save("/home/kikidonk/img.jpg") print '...Saved' def stop(self): self.pipeline.set_state(gst.STATE_NULL) def pause(self): self.pipeline.set_state(gst.STATE_PAUSED) def play(self): self.pipeline.set_state(gst.STATE_PLAYING) def set_window(self, window): self.xwindow = window self.sink.set_xwindow_id(window) def grab_frame(self): self.do_grab_frame = True def set_effect(self, effect, params={}): self.stop() self.csp1.unlink(self.effect) self.effect.unlink(self.csp2) self.pipeline.remove(self.effect) print 'Creating effect:', effect, params self.effect = gst.element_factory_make(effect, "effect") for key, val in params.items(): self.effect.set_property(key, val) self.pipeline.add(self.effect) self.csp1.link(self.effect) self.effect.link(self.csp2) self.play() self.set_window(self.xwindow) class PhotoboothWindow(gtk.Window): def __init__(self, engine): gtk.Window.__init__(self) self.engine = engine self.current_effect = 0 self.set_title("Python Mirror") self.connect("delete_event", self.on_delete_event) self.connect("destroy", self.on_destroy) self.set_border_width(5) self.screen = gtk.DrawingArea() self.screen.set_size_request(500, 380) self.screen.add_events(gtk.gdk.BUTTON_PRESS_MASK) self.screen.connect("expose-event", self.on_expose); self.screen.connect("button_press_event", self.on_click); box = gtk.VBox() box.add(self.screen) button = gtk.Button("Change") button.connect("clicked", self.on_change) box.add(button) self.on_change(None) self.add(box) def on_delete_event(self, widget, event): return False def on_destroy(self, widget): engine.stop() gtk.main_quit() def on_expose(self, dummy1, dummy2): self.engine.set_window(self.screen.window.xid) def on_click(self, dummy1, dummy2): print "Clicked" self.engine.grab_frame() return True def on_change(self, button): self.current_effect += 1 self.engine.set_effect(*EFFECTS[self.current_effect % len(EFFECTS)]) engine = PhotoboothEngine() window = PhotoboothWindow(engine) window.show_all() engine.play() gtk.main()