Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nickbalch/83e206be424d85180c993c25745f9164 to your computer and use it in GitHub Desktop.
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.
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()
@nickbalch
Copy link
Author

Todo:

  • tidy up file list
  • mqtt support
  • weather / other information overlay (via MQTT)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment