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 gtk+ 3.0 -->
|
||||||
<!-- interface-requires camera_mugshot_dialog 1.0 -->
|
<!-- interface-requires camera_mugshot_dialog 1.0 -->
|
||||||
<object class="CameraMugshotDialog" id="camera_mugshot_dialog">
|
<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="can_focus">False</property>
|
||||||
<property name="title" translatable="yes">Capture - Mugshot</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="default_height">300</property>
|
||||||
<property name="icon">../media/mugshot.svg</property>
|
<property name="icon">../media/mugshot.svg</property>
|
||||||
<property name="type_hint">normal</property>
|
<property name="type_hint">normal</property>
|
||||||
|
@ -26,12 +30,13 @@
|
||||||
<property name="homogeneous">True</property>
|
<property name="homogeneous">True</property>
|
||||||
<property name="layout_style">center</property>
|
<property name="layout_style">center</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="button1">
|
<object class="GtkButton" id="camera_cancel">
|
||||||
<property name="label">gtk-cancel</property>
|
<property name="label">gtk-cancel</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
|
<signal name="clicked" handler="on_camera_cancel_clicked" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
|
@ -40,12 +45,14 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="button2">
|
<object class="GtkButton" id="camera_record">
|
||||||
<property name="label">gtk-media-record</property>
|
<property name="label">gtk-media-record</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
|
<signal name="clicked" handler="on_camera_record_clicked" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
|
@ -55,12 +62,14 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="button3">
|
<object class="GtkButton" id="camera_apply">
|
||||||
<property name="label">gtk-apply</property>
|
<property name="label">gtk-apply</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
|
<signal name="clicked" handler="on_camera_apply_clicked" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
|
@ -94,9 +103,9 @@
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<action-widgets>
|
<action-widgets>
|
||||||
<action-widget response="-6">button1</action-widget>
|
<action-widget response="-6">camera_cancel</action-widget>
|
||||||
<action-widget response="0">button2</action-widget>
|
<action-widget response="0">camera_record</action-widget>
|
||||||
<action-widget response="-10">button3</action-widget>
|
<action-widget response="-10">camera_apply</action-widget>
|
||||||
</action-widgets>
|
</action-widgets>
|
||||||
</object>
|
</object>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
|
@ -19,7 +19,10 @@ from locale import gettext as _
|
||||||
import logging
|
import logging
|
||||||
logger = logging.getLogger('mugshot')
|
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
|
from mugshot_lib.CameraDialog import CameraDialog
|
||||||
|
|
||||||
|
@ -35,6 +38,7 @@ class CameraMugshotDialog(CameraDialog):
|
||||||
# Code for other initialization actions should be added here.
|
# Code for other initialization actions should be added here.
|
||||||
vbox = builder.get_object('camera_box')
|
vbox = builder.get_object('camera_box')
|
||||||
self.video_window = Gtk.DrawingArea()
|
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)
|
self.video_window.connect("realize",self.__on_video_window_realized)
|
||||||
vbox.pack_start(self.video_window, True, True, 0)
|
vbox.pack_start(self.video_window, True, True, 0)
|
||||||
self.video_window.show()
|
self.video_window.show()
|
||||||
|
@ -46,8 +50,33 @@ class CameraMugshotDialog(CameraDialog):
|
||||||
bus.connect("message", self._on_message)
|
bus.connect("message", self._on_message)
|
||||||
bus.connect("sync-message::element", self._on_sync_message)
|
bus.connect("sync-message::element", self._on_sync_message)
|
||||||
self.realized = False
|
self.realized = False
|
||||||
|
|
||||||
|
self.record_button = builder.get_object('camera_record')
|
||||||
|
self.apply_button = builder.get_object('camera_apply')
|
||||||
|
|
||||||
self.show_all()
|
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):
|
def play(self):
|
||||||
"""play - Start the camera streaming and display the output. It is
|
"""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.set_property("location", filename)
|
||||||
self.camerabin.emit("start-capture")
|
self.camerabin.emit("start-capture")
|
||||||
|
#self.pause()
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
|
@ -122,16 +152,19 @@ class CameraMugshotDialog(CameraDialog):
|
||||||
return
|
return
|
||||||
|
|
||||||
t = message.type
|
t = message.type
|
||||||
#if t == Gst.MessageType.ASYNC_DONE:
|
if t == Gst.MessageType.ASYNC_DONE:
|
||||||
# print 'finally'
|
self.record_button.set_sensitive(True)
|
||||||
if t == Gst.MessageType.ELEMENT:
|
if t == Gst.MessageType.ELEMENT:
|
||||||
if message.get_structure().get_name() == "image-captured":
|
if message.get_structure().get_name() == "image-captured":
|
||||||
#work around to keep the camera working after lots
|
#work around to keep the camera working after lots
|
||||||
#of pictures are taken
|
#of pictures are taken
|
||||||
self.camerabin.set_state(Gst.Sate.NULL)
|
self.camerabin.set_state(Gst.Sate.NULL)
|
||||||
self.camerabin.set_state(Gst.State.PLAYING)
|
self.camerabin.set_state(Gst.State.PLAYING)
|
||||||
|
|
||||||
self.emit("image-captured", self.filename)
|
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:
|
if t == Gst.MessageType.EOS:
|
||||||
self.camerabin.set_state(Gst.State.NULL)
|
self.camerabin.set_state(Gst.State.NULL)
|
||||||
|
@ -171,6 +204,30 @@ class CameraMugshotDialog(CameraDialog):
|
||||||
if not self.realized and self.video_window.get_window() is not None:
|
if not self.realized and self.video_window.get_window() is not None:
|
||||||
x = self.video_window.get_window().get_xid()
|
x = self.video_window.get_window().get_xid()
|
||||||
self.realized = True
|
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):
|
def on_camera_mugshot_dialog_destroy(self, widget, data=None):
|
||||||
#clean up the camera before exiting
|
#clean up the camera before exiting
|
||||||
|
@ -180,14 +237,32 @@ class CameraMugshotDialog(CameraDialog):
|
||||||
self.pause()
|
self.pause()
|
||||||
|
|
||||||
def on_camera_mugshot_dialog_show(self, widget, data=None):
|
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.show_all()
|
||||||
self.play()
|
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):
|
def on_camera_mugshot_dialog_delete_event(self, widget, data=None):
|
||||||
self.hide()
|
self.hide()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
__gsignals__ = {'image-captured' : (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE,
|
__gsignals__ = {'image-captured' : (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE,
|
||||||
(GObject.TYPE_PYOBJECT,)),
|
(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."""
|
"""Untoggle the image button when the menu is hidden."""
|
||||||
self.image_button.set_active(False)
|
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):
|
def save_image(self):
|
||||||
"""Copy the updated image filename to ~/.face"""
|
"""Copy the updated image filename to ~/.face"""
|
||||||
# Check if the image has been updated.
|
# Check if the image has been updated.
|
||||||
|
|
|
@ -76,19 +76,8 @@ class Window(Gtk.Window):
|
||||||
logger.debug('create new camera_dialog')
|
logger.debug('create new camera_dialog')
|
||||||
self.camera_dialog = self.CameraDialog() # pylint: disable=E1102
|
self.camera_dialog = self.CameraDialog() # pylint: disable=E1102
|
||||||
#self.camera_dialog.connect('destroy', self.on_camera_dialog_destroyed)
|
#self.camera_dialog.connect('destroy', self.on_camera_dialog_destroyed)
|
||||||
|
self.camera_dialog.connect('apply', self.on_camera_dialog_apply)
|
||||||
self.camera_dialog.show()
|
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):
|
def on_destroy(self, widget, data=None):
|
||||||
"""Called when the MugshotWindow is closed."""
|
"""Called when the MugshotWindow is closed."""
|
||||||
|
|
Loading…
Reference in New Issue