Introduction of working camera code.
This commit is contained in:
parent
4a932fa54a
commit
5cc3f035f0
|
@ -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>
|
||||
|
|
|
@ -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,))
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue