@@ -198,6 +198,8 @@ def main():
198
198
type = argparse .FileType ('rb' ))
199
199
parser .add_argument ("--image-grey" , help = "Display a PNG or GIF image in greyscale" ,
200
200
type = argparse .FileType ('rb' ))
201
+ parser .add_argument ("--video" , help = "Play a video" ,
202
+ type = str )
201
203
parser .add_argument ("--percentage" , help = "Fill a percentage of the screen" ,
202
204
type = int )
203
205
parser .add_argument ("--clock" , help = "Display the current time" ,
@@ -341,6 +343,8 @@ def main():
341
343
image_bl (dev , args .image )
342
344
elif args .image_grey is not None :
343
345
image_greyscale (dev , args .image_grey )
346
+ elif args .video is not None :
347
+ video (dev , args .video )
344
348
elif args .all_brightnesses :
345
349
all_brightnesses (dev )
346
350
elif args .set_color :
@@ -559,6 +563,51 @@ def image_bl(dev, image_file):
559
563
560
564
send_command (dev , CommandVals .Draw , vals )
561
565
566
+ def video (dev , video_file ):
567
+ """Resize and play back a video"""
568
+ with serial .Serial (dev .device , 115200 ) as s :
569
+ import cv2
570
+
571
+ capture = cv2 .VideoCapture (video_file )
572
+ ret , frame = capture .read ()
573
+
574
+ scale_x = WIDTH / frame .shape [1 ]
575
+ scale_y = HEIGHT / frame .shape [0 ]
576
+
577
+ # Scale the video to 34 pixels height
578
+ dim = (HEIGHT , int (round (frame .shape [1 ]* scale_y )))
579
+ # Find the starting position to crop the width to be centered
580
+ # For very narrow videos, make sure to stay in bounds
581
+ start_x = max (0 , int (round (dim [1 ]/ 2 - WIDTH / 2 )))
582
+ end_x = min (dim [1 ], start_x + WIDTH )
583
+
584
+ processed = []
585
+
586
+ # Pre-process the video into resized, cropped, grayscale frames
587
+ while True :
588
+ ret , frame = capture .read ()
589
+ if not ret :
590
+ break
591
+
592
+ gray = cv2 .cvtColor (frame , cv2 .COLOR_RGB2GRAY )
593
+
594
+ resized = cv2 .resize (gray , (dim [1 ], dim [0 ]))
595
+ cropped = resized [0 :HEIGHT , start_x :end_x ]
596
+
597
+ processed .append (cropped )
598
+
599
+ # Write it out to the module one frame at a time
600
+ # TODO: actually control for framerate
601
+ for frame in processed :
602
+ for x in range (0 , cropped .shape [1 ]):
603
+ vals = [0 for _ in range (HEIGHT )]
604
+
605
+ for y in range (0 , HEIGHT ):
606
+ vals [y ] = frame [y , x ]
607
+
608
+ send_col (s , x , vals )
609
+ commit_cols (s )
610
+
562
611
563
612
def pixel_to_brightness (pixel ):
564
613
"""Calculate pixel brightness from an RGB triple"""
0 commit comments