Last active
August 7, 2020 18:54
-
-
Save nickbalch/83e206be424d85180c993c25745f9164 to your computer and use it in GitHub Desktop.
Incomplete Picture Frame / Photo Slideshow Python code for Raspberry Pi and Touchscreen Display using Framebuffer.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import stat | |
import pygame | |
import time | |
import random | |
# https://learn.adafruit.com/pi-video-output-using-pygame/pointing-pygame-to-the-framebuffer | |
drivers = ['directfb', 'fbcon', 'svgalib'] | |
background = (255,255,0) | |
found = False | |
for driver in drivers: | |
if not os.getenv('SDL_VIDEODRIVER'): | |
os.putenv('SDL_VIDEODRIVER', driver) | |
try: | |
pygame.display.init() | |
except pygame.error: | |
print ('Driver: {0} failed.'.format(driver)) | |
continue | |
found = True | |
break | |
if not found: | |
raise Exception('No suitable video driver found!') | |
def main(startdir="/media/frame/flickr"): | |
global file_list, title, waittime | |
pygame.init() | |
if not pygame.image.get_extended(): | |
print ("Your Pygame isn't built with extended image support.") | |
print ("It's likely this isn't going to work.") | |
walktree(startdir, addtolist) # this may take a while... | |
if len(file_list) == 0: | |
print ("Sorry. No images found. Exiting.") | |
sys.exit(1) | |
random.shuffle(file_list) | |
modes = pygame.display.list_modes() | |
# print (modes) | |
# print (max(modes)) | |
# pygame.display.set_mode(max(modes)) | |
pygame.display.set_mode((800,480)) | |
screen = pygame.display.get_surface() | |
pygame.display.set_caption(title) | |
pygame.display.toggle_fullscreen() | |
current = 0 | |
alpha = 0 | |
alpha2 = 255 | |
num_files = len(file_list) | |
screen.fill((0,0,0)) | |
# https://github.com/bradmontgomery/pgSlideShow | |
while(True): | |
try: | |
img = pygame.image.load(file_list[current]) | |
img = img.convert_alpha() | |
# rescale the image to fit the current display | |
#img = pygame.transform.scale(img, max(modes)) | |
scr = (max(modes)) | |
scr = ((800,480)) | |
#print (scr[0]) | |
img = aspect_scale(img,scr[0],scr[1]) | |
img_rect = img.get_rect(center = screen.get_rect().center) | |
while alpha >0 and alpha2 < 255: | |
if alpha > 0: | |
# Reduce alpha each frame. | |
alpha -= 4 | |
alpha = max(0, alpha) # Make sure it doesn't go below 0. | |
surf = change_alpha(img_old, alpha) | |
if alpha2 < 255: | |
alpha2 += 4 | |
alpha2 = min(255, alpha2) | |
surf2 = change_alpha(img, alpha2) | |
screen.fill((0, 0, 0)) | |
screen.blit(surf, img_rect_old) | |
screen.blit(surf2, img_rect) | |
pygame.display.flip() | |
# print ("wait") | |
# time.sleep(waittime) | |
except pygame.error as err: | |
print ("Failed to display %s: %s" % (file_list[current], err)) | |
# When we get to the end, re-start at the beginning | |
current = (current + 1) % num_files; | |
alpha = 255 | |
alpha2 = 0 | |
img_old = img | |
img_rect_old = img_rect | |
screen.blit(img_old, img_rect_old) | |
pygame.display.update() | |
time.sleep(waittime) | |
def change_alpha(orig_surf, alpha): | |
"""Create a copy of orig_surf with the desired alpha value. | |
https://stackoverflow.com/questions/47682103/pygame-smooth-transform-of-image-surface | |
This function creates another surface with the desired alpha | |
value and then blits it onto the copy of the original surface | |
with the `BLEND_RGBA_MULT` flag to change the transparency.""" | |
surf = orig_surf.copy() | |
# This surface is used to adjust the alpha of the txt_surf. | |
alpha_surf = pygame.Surface(surf.get_size(), pygame.SRCALPHA) | |
# alpha_surf = pygame.Surface((800,480), pygame.SRCALPHA) | |
alpha_surf.fill((255, 255, 255, alpha)) # Set the alpha value. | |
surf.blit(alpha_surf, (0, 0), special_flags=pygame.BLEND_RGBA_MULT) | |
return surf | |
def walktree(top, callback): | |
"""recursively descend the directory tree rooted at top, calling the | |
callback function for each regular file. Taken from the module-stat | |
example at: http://docs.python.org/lib/module-stat.html | |
""" | |
for f in os.listdir(top): | |
pathname = os.path.join(top, f) | |
mode = os.stat(pathname)[stat.ST_MODE] | |
if stat.S_ISDIR(mode): | |
# It's a directory, recurse into it | |
walktree(pathname, callback) | |
elif stat.S_ISREG(mode): | |
# It's a file, call the callback function | |
callback(pathname) | |
else: | |
# Unknown file type, print a message | |
print ('Skipping %s' % pathname) | |
def addtolist(file, extensions=['.png', '.jpg', '.jpeg', '.gif', '.bmp']): | |
"""Add a file to a global list of image files.""" | |
global file_list # ugh | |
filename, ext = os.path.splitext(file) | |
e = ext.lower() | |
# Only add common image types to the list. | |
if e in extensions: | |
print ('Adding to list: ', file) | |
file_list.append(file) | |
else: | |
print ('Skipping: ', file, ' (NOT a supported image)') | |
def aspect_scale(img,bx,by): | |
##http://www.pygame.org/pcr/transform_scale Scales 'img' to fit into box bx/by. | |
## This method will retain the original image's aspect ratio """ | |
ix,iy = img.get_size() | |
if ix > iy: | |
# fit to width | |
scale_factor = bx/float(ix) | |
sy = scale_factor * iy | |
if sy > by: | |
scale_factor = by/float(iy) | |
sx = scale_factor * ix | |
sy = by | |
else: | |
sx = bx | |
else: | |
# fit to height | |
scale_factor = by/float(iy) | |
sx = scale_factor * ix | |
if sx > bx: | |
scale_factor = bx/float(ix) | |
sx = bx | |
sy = scale_factor * iy | |
else: | |
sy = by | |
return pygame.transform.scale(img,(int(sx),int(sy))) | |
title = "test" | |
waittime = 5 | |
file_list = [] | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Todo: