Introduction of working camera code.

This commit is contained in:
Sean Davis 2013-07-15 20:48:29 -04:00
parent 4a932fa54a
commit 5cc3f035f0
4 changed files with 100 additions and 23 deletions

View File

@ -3,8 +3,12 @@
<!-- interface-requires gtk+ 3.0 -->
<!-- interface-requires camera_mugshot_dialog 1.0 -->
<object class="CameraMugshotDialog" id="camera_mugshot_dialog">
<property name="width_request">230</property>
<property name="height_request">300</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Capture - Mugshot</property>
<property name="resizable">False</property>
<property name="default_width">230</property>
<property name="default_height">300</property>
<property name="icon">../media/mugshot.svg</property>
<property name="type_hint">normal</property>
@ -26,12 +30,13 @@
<property name="homogeneous">True</property>
<property name="layout_style">center</property>
<child>
<object class="GtkButton" id="button1">
<object class="GtkButton" id="camera_cancel">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_camera_cancel_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@ -40,12 +45,14 @@
</packing>
</child>
<child>
<object class="GtkButton" id="button2">
<object class="GtkButton" id="camera_record">
<property name="label">gtk-media-record</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">False</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_camera_record_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@ -55,12 +62,14 @@
</packing>
</child>
<child>
<object class="GtkButton" id="button3">
<object class="GtkButton" id="camera_apply">
<property name="label">gtk-apply</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">False</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_camera_apply_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@ -94,9 +103,9 @@
</object>
</child>
<action-widgets>
<action-widget response="-6">button1</action-widget>
<action-widget response="0">button2</action-widget>
<action-widget response="-10">button3</action-widget>
<action-widget response="-6">camera_cancel</action-widget>
<action-widget response="0">camera_record</action-widget>
<action-widget response="-10">camera_apply</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -19,7 +19,10 @@ from locale import gettext as _
import logging
logger = logging.getLogger('mugshot')
from gi.repository import Gtk, GdkX11, GObject, Gst, GstVideo
from gi.repository import Gtk, GdkX11, GObject, Gst, GstVideo, GdkPixbuf
import cairo
import tempfile, os
from mugshot_lib.CameraDialog import CameraDialog
@ -35,6 +38,7 @@ class CameraMugshotDialog(CameraDialog):
# Code for other initialization actions should be added here.
vbox = builder.get_object('camera_box')
self.video_window = Gtk.DrawingArea()
self.draw_handler = self.video_window.connect('draw', self.on_draw)
self.video_window.connect("realize",self.__on_video_window_realized)
vbox.pack_start(self.video_window, True, True, 0)
self.video_window.show()
@ -46,8 +50,33 @@ class CameraMugshotDialog(CameraDialog):
bus.connect("message", self._on_message)
bus.connect("sync-message::element", self._on_sync_message)
self.realized = False
self.record_button = builder.get_object('camera_record')
self.apply_button = builder.get_object('camera_apply')
self.show_all()
##self.play()
self.filename = None
def on_draw(self, widget, ctx):
alloc = widget.get_allocation()
height = alloc.height
width = alloc.width
font_size = 20
ctx.set_source_rgb(255,255,255)
ctx.select_font_face("Sans", cairo.FONT_SLANT_NORMAL,
cairo.FONT_WEIGHT_NORMAL)
ctx.set_font_size(20)
ctx.move_to(10,(height-font_size)/2)
ctx.show_text(_("Please wait while your"))
ctx.move_to(10,(height-font_size)/2+20)
ctx.show_text(_("camera is initialized."))
widget.disconnect(self.draw_handler)
self.draw_handler = widget.connect('draw', self.on_blank)
def on_blank(self, widget, ctx):
ctx.set_source_rgb(0,0,0)
ctx.paint()
def play(self):
"""play - Start the camera streaming and display the output. It is
@ -95,6 +124,7 @@ class CameraMugshotDialog(CameraDialog):
"""
self.camerabin.set_property("location", filename)
self.camerabin.emit("start-capture")
#self.pause()
return filename
def stop(self):
@ -122,16 +152,19 @@ class CameraMugshotDialog(CameraDialog):
return
t = message.type
#if t == Gst.MessageType.ASYNC_DONE:
# print 'finally'
if t == Gst.MessageType.ASYNC_DONE:
self.record_button.set_sensitive(True)
if t == Gst.MessageType.ELEMENT:
if message.get_structure().get_name() == "image-captured":
#work around to keep the camera working after lots
#of pictures are taken
self.camerabin.set_state(Gst.Sate.NULL)
self.camerabin.set_state(Gst.State.PLAYING)
self.emit("image-captured", self.filename)
elif message.get_structure().get_name() == "image-done":
self.apply_button.set_sensitive(True)
self.record_button.set_sensitive(True)
self.pause()
if t == Gst.MessageType.EOS:
self.camerabin.set_state(Gst.State.NULL)
@ -172,6 +205,30 @@ class CameraMugshotDialog(CameraDialog):
x = self.video_window.get_window().get_xid()
self.realized = True
def on_camera_record_clicked(self, widget):
if self.filename: os.remove(self.filename)
if self.apply_button.get_sensitive():
# Retry mode
self.record_button.set_label(Gtk.STOCK_MEDIA_RECORD)
self.apply_button.set_sensitive(False)
self.play()
else:
tmpfile = tempfile.NamedTemporaryFile(delete=False)
tmpfile.close()
self.filename = tmpfile.name
self.take_picture(self.filename)
self.record_button.set_label(_("Retry"))
self.record_button.set_sensitive(False)
#self.apply_button.set_sensitive(True)
def on_camera_apply_clicked(self, widget):
self.center_crop(self.filename)
self.emit( "apply", self.filename )
self.hide()
def on_camera_cancel_clicked(self, widget):
self.hide()
def on_camera_mugshot_dialog_destroy(self, widget, data=None):
#clean up the camera before exiting
self.camerabin.set_state(Gst.State.NULL)
@ -180,14 +237,32 @@ class CameraMugshotDialog(CameraDialog):
self.pause()
def on_camera_mugshot_dialog_show(self, widget, data=None):
self.record_button.set_label(Gtk.STOCK_MEDIA_RECORD)
self.apply_button.set_sensitive(False)
self.show_all()
self.play()
def center_crop(self, filename):
pixbuf = GdkPixbuf.Pixbuf.new_from_file(filename)
height = pixbuf.get_height()
width = pixbuf.get_width()
start_x = 0
start_y = 0
if width > height:
start_x = (width-height)/2
width = height
else:
start_y = (height-width)/2
height = width
new_pixbuf = pixbuf.new_subpixbuf(start_x, start_y, width, height)
new_pixbuf.savev(filename, "png", [], [])
def on_camera_mugshot_dialog_delete_event(self, widget, data=None):
self.hide()
return True
__gsignals__ = {'image-captured' : (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE,
(GObject.TYPE_PYOBJECT,)),
'apply' : (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (GObject.TYPE_STRING,))
}

View File

@ -245,6 +245,10 @@ class MugshotWindow(Window):
"""Untoggle the image button when the menu is hidden."""
self.image_button.set_active(False)
def on_camera_dialog_apply(self, widget, data=None):
self.updated_image = data
self.set_user_image(data)
def save_image(self):
"""Copy the updated image filename to ~/.face"""
# Check if the image has been updated.

View File

@ -76,20 +76,9 @@ class Window(Gtk.Window):
logger.debug('create new camera_dialog')
self.camera_dialog = self.CameraDialog() # pylint: disable=E1102
#self.camera_dialog.connect('destroy', self.on_camera_dialog_destroyed)
self.camera_dialog.connect('apply', self.on_camera_dialog_apply)
self.camera_dialog.show()
#def on_camera_dialog_destroyed(self, widget, data=None):
# '''only affects gui
#
# logically there is no difference between the user closing,
# minimising or ignoring the camera dialog'''
# logger.debug('on_camera_dialog_destroyed')
# # to determine whether to create or present camera_dialog
# self.camera_dialog.hide()
# #self.camera_dialog = None
def on_destroy(self, widget, data=None):
"""Called when the MugshotWindow is closed."""
# Clean up code for saving application state should be added here.