Skip to content

Commit 585dba4

Browse files
Merge pull request #28 from laurentalacoque/mirrored-preview
Mirrored preview is functionnal
2 parents 3cc0548 + b639718 commit 585dba4

File tree

10 files changed

+109
-7
lines changed

10 files changed

+109
-7
lines changed

scripts/constants.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
name of the automaticaly generated credentials store (relative to scripts/ directory)
2525
2626
"""
27-
27+
import os
2828
SCREEN_W = 800 ## raspi touch
2929
SCREEN_H = 480 ## raspi touch
3030

@@ -48,13 +48,13 @@
4848

4949
SOFTWARE_BUTTONS = {
5050
"None": {
51-
"icon" : "ressources/ic_photo.png"
51+
"icon" : os.path.join("ressources","ic_photo.png")
5252
},
5353
"Four": {
54-
"icon" : "ressources/ic_portrait.png"
54+
"icon" : os.path.join("ressources","ic_portrait.png")
5555
},
5656
"Animation": {
57-
"icon" : "ressources/ic_anim.png"
57+
"icon" : os.path.join("ressources","ic_anim.png")
5858
}
5959
}
6060

@@ -72,7 +72,15 @@
7272
"configure":["<Escape>"]
7373
}
7474

75-
EMAIL_BUTTON_IMG = "ressources/ic_email.png"
75+
COUNTDOWN_OVERLAY_IMAGES=[
76+
os.path.join("ressources","count_down_1.png"),
77+
os.path.join("ressources","count_down_2.png"),
78+
os.path.join("ressources","count_down_3.png"),
79+
os.path.join("ressources","count_down_4.png"),
80+
os.path.join("ressources","count_down_5.png"),
81+
os.path.join("ressources","count_down_ready.png")]
82+
83+
EMAIL_BUTTON_IMG = os.path.join("ressources","ic_email.png")
7684
OAUTH2_REFRESH_PERIOD = 1800000 # interval between two OAuth2 token refresh (ms)
7785
HARDWARE_POLL_PERIOD = 100 # poll interval for buttons (ms)
7886

scripts/fakehardware.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ def __init__(self,color):
1212

1313
class DummyPreview:
1414
"""Dummy Preview class for camera.preview"""
15+
window=(0,0,640,480)
1516
def __init__(self):
1617
self.annotate_text = ""
17-
18+
class FakeOverlay:
19+
layer=0
20+
pass
1821
class PiCamera:
1922
'''
2023
Fake PiCamera class to generate test images
@@ -51,7 +54,14 @@ def capture(self, filename, resize=None):
5154
im = im.convert('RGB')
5255
im.save(filename)
5356
return True
54-
57+
58+
def add_overlay(self,overlay_image, size=(640,480)):
59+
return FakeOverlay()
60+
pass
61+
62+
def remove_overlay(self,overlay):
63+
pass
64+
5565
def capture_continuous(self, output):
5666
"""Generate a sequence of test images"""
5767
#'animframe-{counter:03d}.jpg'

scripts/ressources/count_down_1.png

2.27 KB
Loading

scripts/ressources/count_down_2.png

3.42 KB
Loading

scripts/ressources/count_down_3.png

3.78 KB
Loading

scripts/ressources/count_down_4.png

2.53 KB
Loading

scripts/ressources/count_down_5.png

3.36 KB
Loading
4.53 KB
Loading
15.6 KB
Binary file not shown.

scripts/user_interface.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,11 @@ def __countdown_set_led(self,state):
488488
pass
489489

490490
def __show_countdown(self,countdown,annotate_size=160):
491+
'''wrapper function to select between overlay and text countdowns'''
492+
#self.__show_text_countdown(countdown,annotate_size=annotate_size)
493+
self.__show_overlay_countdown(countdown)
494+
495+
def __show_text_countdown(self,countdown,annotate_size=160):
491496
''' display countdown. the camera should have a preview active and the resolution must be set'''
492497
led_state = False
493498
self.__countdown_set_led(led_state)
@@ -513,7 +518,86 @@ def __show_countdown(self,countdown,annotate_size=160):
513518
led_state = not led_state
514519
self.__countdown_set_led(led_state)
515520
self.camera.annotate_text = ""
521+
522+
def __show_overlay_countdown(self,countdown):
523+
"""Display countdown as images overlays"""
524+
#COUNTDOWN_OVERLAY_IMAGES
525+
led_state = False
526+
self.__countdown_set_led(led_state)
527+
528+
self.camera.preview.fullscreen = True
529+
self.camera.preview.hflip = True #Mirror effect for easier selfies
530+
#for some reason camera.preview.window =(0,0,0,0)
531+
#bbox = self.camera.preview.window
532+
#preview_width = bbox[2]
533+
#preview_height = bbox[3]
534+
preview_size = self.camera.resolution
535+
preview_width = preview_size[0]
536+
preview_height = preview_size[1]
537+
538+
overlay_height = int(preview_height * 0.2)
539+
print preview_size
540+
print preview_width, preview_height, overlay_height
541+
542+
## prepare overlay images (resize)
543+
overlay_images = []
544+
for i in range(countdown):
545+
if i >= len(COUNTDOWN_OVERLAY_IMAGES):
546+
break;
547+
#read overlay image
548+
im = Image.open(COUNTDOWN_OVERLAY_IMAGES[i])
549+
#resize to 20% of height
550+
im.thumbnail((preview_width,overlay_height))
551+
552+
#overlays should be padded to 32 (width) and 16 (height)
553+
pad_width = int((preview_width + 31) / 32) * 32
554+
pad_height = int((preview_height + 15) / 16) * 16
555+
556+
padded_overlay = Image.new('RGBA', (pad_width, pad_height))
557+
# Paste the original image into the padded one (centered)
558+
padded_overlay.paste(im, ( int((preview_width+im.size[0])/2.0), int((preview_height+im.size[1])/2.0)))
559+
overlay_images.append(padded_overlay)
560+
## All images loaded at the right resolution
516561

562+
#Change overlay every second and blink led
563+
for i in range(countdown):
564+
#what overlay image to select:
565+
overlay_image = None
566+
overlay_image_num = countdown -1 -i #5-1-0 ==> 4 ; 5-1-4 ==> 0
567+
if overlay_image_num >= len(overlay_images):
568+
overlay_image = overlay_images[len(overlay_images)-1]
569+
elif overlay_image_num < 0:
570+
overlay_image = None
571+
else:
572+
overlay_image = overlay_images[overlay_image_num]
573+
## Add overlay to image
574+
overlay = None
575+
if overlay_image != None:
576+
#create overlay
577+
overlay = self.camera.add_overlay(overlay_image.tobytes(), size=overlay_image.size)
578+
#move it on top of preview
579+
overlay.layer = 3
580+
#change transparency
581+
overlay.alpha = 128
582+
#flip it horizontally (because preview is flipped)
583+
#overlay.hflip = True
584+
585+
if i < countdown - 2:
586+
# slow blink until -2s
587+
time.sleep(1)
588+
led_state = not led_state
589+
self.__countdown_set_led(led_state)
590+
else:
591+
# fast blink until the end
592+
for j in range(5):
593+
time.sleep(.2)
594+
led_state = not led_state
595+
self.__countdown_set_led(led_state)
596+
if overlay != None:
597+
self.camera.remove_overlay(overlay)
598+
599+
600+
517601
def refresh_auth(self):
518602
""" refresh the oauth2 service (regularly called)"""
519603
# useless if we don't need image upload

0 commit comments

Comments
 (0)