Advertisement
Guest User

python slideshow

a guest
Dec 6th, 2013
1,022
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.36 KB | None | 0 0
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # Taken and customed from Jack Valmadre's Blog:
  5. # http://jackvalmadre.wordpress.com/2008/09/21/resizable-image-control/
  6. #
  7. # Put together and created the time switching by Izidor Matusov <izidor.matusov@gmail.com>
  8.  
  9. import os
  10.  
  11. import pygtk
  12. pygtk.require('2.0')
  13. import gtk
  14. import glib
  15.  
  16. def is_image(filename):
  17.     """ File is image if it has a common suffix and it is a regular file """
  18.  
  19.     if not os.path.isfile(filename):
  20.         return False
  21.  
  22.     for suffix in ['.jpg', '.png', '.bmp']:
  23.         if filename.lower().endswith(suffix):
  24.             return True
  25.  
  26.     return False
  27.  
  28. def resizeToFit(image, frame, aspect=True, enlarge=False):
  29.     """Resizes a rectangle to fit within another.
  30.  
  31.    Parameters:
  32.    image -- A tuple of the original dimensions (width, height).
  33.    frame -- A tuple of the target dimensions (width, height).
  34.    aspect -- Maintain aspect ratio?
  35.    enlarge -- Allow image to be scaled up?
  36.  
  37.    """
  38.     if aspect:
  39.         return scaleToFit(image, frame, enlarge)
  40.     else:
  41.         return stretchToFit(image, frame, enlarge)
  42.  
  43. def scaleToFit(image, frame, enlarge=False):
  44.     image_width, image_height = image
  45.     frame_width, frame_height = frame
  46.     image_aspect = float(image_width) / image_height
  47.     frame_aspect = float(frame_width) / frame_height
  48.     # Determine maximum width/height (prevent up-scaling).
  49.     if not enlarge:
  50.         max_width = min(frame_width, image_width)
  51.         max_height = min(frame_height, image_height)
  52.     else:
  53.         max_width = frame_width
  54.         max_height = frame_height
  55.     # Frame is wider than image.
  56.     if frame_aspect > image_aspect:
  57.         height = max_height
  58.         width = int(height * image_aspect)
  59.     # Frame is taller than image.
  60.     else:
  61.         width = max_width
  62.         height = int(width / image_aspect)
  63.     return (width, height)
  64.  
  65. def stretchToFit(image, frame, enlarge=False):
  66.     image_width, image_height = image
  67.     frame_width, frame_height = frame
  68.     # Stop image from being blown up.
  69.     if not enlarge:
  70.         width = min(frame_width, image_width)
  71.         height = min(frame_height, image_height)
  72.     else:
  73.         width = frame_width
  74.         height = frame_height
  75.     return (width, height)
  76.  
  77.  
  78. class ResizableImage(gtk.DrawingArea):
  79.  
  80.     def __init__(self, aspect=True, enlarge=False,
  81.             interp=gtk.gdk.INTERP_NEAREST, backcolor=None, max=(1600,1200)):
  82.         """Construct a ResizableImage control.
  83.  
  84.        Parameters:
  85.        aspect -- Maintain aspect ratio?
  86.        enlarge -- Allow image to be scaled up?
  87.        interp -- Method of interpolation to be used.
  88.        backcolor -- Tuple (R, G, B) with values ranging from 0 to 1,
  89.            or None for transparent.
  90.        max -- Max dimensions for internal image (width, height).
  91.  
  92.        """
  93.         super(ResizableImage, self).__init__()
  94.         self.pixbuf = None
  95.         self.aspect = aspect
  96.         self.enlarge = enlarge
  97.         self.interp = interp
  98.         self.backcolor = backcolor
  99.         self.max = max
  100.         self.connect('expose_event', self.expose)
  101.         self.connect('realize', self.on_realize)
  102.  
  103.     def on_realize(self, widget):
  104.         if self.backcolor is None:
  105.             color = gtk.gdk.Color()
  106.         else:
  107.             color = gtk.gdk.Color(*self.backcolor)
  108.  
  109.         self.window.set_background(color)
  110.  
  111.     def expose(self, widget, event):
  112.         # Load Cairo drawing context.
  113.         self.context = self.window.cairo_create()
  114.         # Set a clip region.
  115.         self.context.rectangle(
  116.             event.area.x, event.area.y,
  117.             event.area.width, event.area.height)
  118.         self.context.clip()
  119.         # Render image.
  120.         self.draw(self.context)
  121.         return False
  122.  
  123.     def draw(self, context):
  124.         # Get dimensions.
  125.         rect = self.get_allocation()
  126.         x, y = rect.x, rect.y
  127.         # Remove parent offset, if any.
  128.         parent = self.get_parent()
  129.         if parent:
  130.             offset = parent.get_allocation()
  131.             x -= offset.x
  132.             y -= offset.y
  133.         # Fill background color.
  134.         if self.backcolor:
  135.             context.rectangle(x, y, rect.width, rect.height)
  136.             context.set_source_rgb(*self.backcolor)
  137.             context.fill_preserve()
  138.         # Check if there is an image.
  139.         if not self.pixbuf:
  140.             return
  141.         width, height = resizeToFit(
  142.             (self.pixbuf.get_width(), self.pixbuf.get_height()),
  143.             (rect.width, rect.height),
  144.             self.aspect,
  145.             self.enlarge)
  146.         x = x + (rect.width - width) / 2
  147.         y = y + (rect.height - height) / 2
  148.         context.set_source_pixbuf(
  149.             self.pixbuf.scale_simple(width, height, self.interp), x, y)
  150.         context.paint()
  151.  
  152.     def set_from_pixbuf(self, pixbuf):
  153.         width, height = pixbuf.get_width(), pixbuf.get_height()
  154.         # Limit size of internal pixbuf to increase speed.
  155.         if not self.max or (width < self.max[0] and height < self.max[1]):
  156.             self.pixbuf = pixbuf
  157.         else:
  158.             width, height = resizeToFit((width, height), self.max)
  159.             self.pixbuf = pixbuf.scale_simple(
  160.                 width, height,
  161.                 gtk.gdk.INTERP_BILINEAR)
  162.         self.invalidate()
  163.  
  164.     def set_from_file(self, filename):
  165.         self.set_from_pixbuf(gtk.gdk.pixbuf_new_from_file(filename))
  166.  
  167.     def invalidate(self):
  168.         self.queue_draw()
  169.  
  170. class DemoGtk:
  171.  
  172.     SECONDS_BETWEEN_PICTURES = 1
  173.     FULLSCREEN = True
  174.     WALK_INSTEAD_LISTDIR = True
  175.  
  176.  
  177.     def __init__(self):
  178.         self.window = gtk.Window()
  179.         self.window.connect('destroy', gtk.main_quit)
  180.         self.window.set_title('Slideshow')
  181.  
  182.         self.image = ResizableImage( True, True, gtk.gdk.INTERP_BILINEAR)
  183.         self.image.show()
  184.         self.window.add(self.image)
  185.  
  186.         self.load_file_list()
  187.  
  188.         self.window.show_all()
  189.  
  190.         if self.FULLSCREEN:
  191.             self.window.fullscreen()
  192.  
  193.         glib.timeout_add_seconds(self.SECONDS_BETWEEN_PICTURES, self.on_tick)
  194.         self.display()
  195.        
  196.  
  197.     def load_file_list(self):
  198.         """ Find all images """
  199.         self.files = []
  200.         self.index = 0
  201.  
  202.         if self.WALK_INSTEAD_LISTDIR:
  203.             for directory, sub_directories, files in os.walk('.'):
  204.                 for filename in files:
  205.                     if is_image(filename):
  206.                         filepath = os.path.join(directory, filename)
  207.                         self.files.append(filepath)
  208.         else:
  209.             for filename in os.listdir('.'):
  210.                 if is_image(filename):
  211.                     self.files.append(filename)
  212.  
  213.         print "Images:", self.files
  214.  
  215.     def display(self):
  216.         """ Sent a request to change picture if it is possible """
  217.         if 0 <= self.index < len(self.files):
  218.             self.image.set_from_file(self.files[self.index])
  219.             return True
  220.         else:
  221.             return False
  222.  
  223.  
  224.     def on_tick(self):
  225.         """ Skip to another picture.
  226.  
  227.        If this picture is last, go to the first one. """
  228.         self.index += 1
  229.         if self.index >= len(self.files):
  230.             self.index = -1
  231.             # ^ this stops on the last photo ^
  232.  
  233.         return self.display()
  234.  
  235. if __name__ == "__main__":
  236.     gui = DemoGtk()
  237.     gtk.main()
  238.  
  239. # vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement