forked from bnjmnp/pibooth
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gphoto_omx.py
126 lines (105 loc) · 4.5 KB
/
gphoto_omx.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# -*- coding: utf-8 -*-
import os
import time
import signal
import subprocess
from PIL import Image
from pibooth.utils import PoolingTimer, memorize
from pibooth.language import get_translated_text
from pibooth.camera.gphoto import gp, gp_camera_connected, GpCamera
@memorize
def gpomx_camera_connected():
"""Return True if a camera compatible with gPhoto2 is found.
"""
return False # This camera is not yet implemented
try:
process = subprocess.Popen(['omxplayer', '--version'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process.communicate()
if process.returncode != 0:
return False
except OSError:
return False
return gp_camera_connected()
class GpOmxCamera(GpCamera):
"""gPhoto2 camera management using Omxplayer as preview.
"""
def __init__(self, *args, **kwargs):
kwargs['init'] = False
GpCamera.__init__(self, *args, **kwargs)
self.gphoto2_process = None
self.omxplayer_process = None
def _initialize(self):
"""Camera initialisation
"""
self._cam = gp.Camera()
self._cam.init()
self.set_config_value('imgsettings', 'iso', self._iso)
self.set_config_value('settings', 'capturetarget', 'Memory card')
def _show_overlay(self, text, alpha):
"""Add an image as an overlay.
"""
if self._window: # No window means no preview displayed
rect = self._window.get_rect()
size = (((rect.width + 31) // 32) * 32, ((rect.height + 15) // 16) * 16)
image = Image.new('RGB', size, color=(0, 0, 0))
self._overlay = self.build_overlay(image.size, text, alpha)
image.paste(self._overlay, (0, 0), self._overlay)
self._window.show_image(image)
def preview(self, window, flip=True):
"""Setup the preview.
"""
self._window = window
if not self.gphoto2_process:
rect = self.get_rect()
if flip:
orientation = 1
else:
orientation = 0
self.gphoto2_process = subprocess.Popen("gphoto2 --capture-movie --stdout> fifo.mjpg &",
shell=True,
preexec_fn=os.setsid)
window_rect = '{0},{1},{2},{3}'.format(tuple(rect)[0], tuple(rect)[1], tuple(rect)[0] + tuple(rect)[2],
tuple(rect)[1] + tuple(rect)[3])
command = "omxplayer fifo.mjpg --live --crop 252,0,804,704 --win {0} --orientation {1}".format(
window_rect, orientation)
self.omxplayer_process = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
def preview_countdown(self, timeout, alpha=60):
"""Show a countdown of `timeout` seconds on the preview.
Returns when the countdown is finished.
"""
timeout = int(timeout)
if timeout < 1:
raise ValueError("Start time shall be greater than 0")
timer = PoolingTimer(timeout)
while not timer.is_timeout():
self.preview(self._window)
remaining = int(timer.remaining() + 1)
if not self._overlay or remaining != timeout:
# Rebluid overlay only if remaining number has changed
self._show_overlay(str(remaining), alpha)
timeout = remaining
self._show_overlay(get_translated_text('smile'), alpha)
def preview_wait(self, timeout, alpha=60):
"""Wait the given time.
"""
time.sleep(timeout)
self._show_overlay(get_translated_text('smile'), alpha)
def stop_preview(self):
"""Stop the preview.
"""
if self.omxplayer_process:
os.killpg(os.getpgid(self.omxplayer_process.pid), signal.SIGTERM)
self.omxplayer_process = None
self._window = None
def capture(self, effect=None):
"""Capture a picture in a file.
"""
effect = str(effect).lower()
if effect not in self.IMAGE_EFFECTS:
raise ValueError("Invalid capture effect '{}' (choose among {})".format(effect, self.IMAGE_EFFECTS))
self._initialize()
self._captures.append((self._cam.capture(gp.GP_CAPTURE_IMAGE), effect))
time.sleep(1) # Necessary to let the time for the camera to save the image
self.quit()
self._hide_overlay() # If stop_preview() has not been called