【问题标题】:Using pygtk how can I make a simple fullscreen slide show使用 pygtk 如何制作简单的全屏幻灯片
【发布时间】:2011-07-22 05:49:49
【问题描述】:

如何使用 pygtk 制作全屏幻灯片,在目录中的所有图像中旋转,每 x 秒切换一次

【问题讨论】:

    标签: python pygtk slideshow fullscreen


    【解决方案1】:

    过去我写的完全一样。然后我把它删了。此版本使用准备好的代码在缩放图像时曝光图像。取自Jack Valmadre’s Blog

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    #
    # Taken and customed from Jack Valmadre's Blog:
    # http://jackvalmadre.wordpress.com/2008/09/21/resizable-image-control/
    #
    # Put together and created the time switching by Izidor Matusov <izidor.matusov@gmail.com>
    
    import os
    
    import pygtk
    pygtk.require('2.0')
    import gtk
    import glib
    
    def is_image(filename):
        """ File is image if it has a common suffix and it is a regular file """
    
        if not os.path.isfile(filename):
            return False
    
        for suffix in ['.jpg', '.png', '.bmp']:
            if filename.lower().endswith(suffix):
                return True
    
        return False
    
    def resizeToFit(image, frame, aspect=True, enlarge=False):
        """Resizes a rectangle to fit within another.
    
        Parameters:
        image -- A tuple of the original dimensions (width, height).
        frame -- A tuple of the target dimensions (width, height).
        aspect -- Maintain aspect ratio?
        enlarge -- Allow image to be scaled up?
    
        """
        if aspect:
            return scaleToFit(image, frame, enlarge)
        else:
            return stretchToFit(image, frame, enlarge)
    
    def scaleToFit(image, frame, enlarge=False):
        image_width, image_height = image
        frame_width, frame_height = frame
        image_aspect = float(image_width) / image_height
        frame_aspect = float(frame_width) / frame_height
        # Determine maximum width/height (prevent up-scaling).
        if not enlarge:
            max_width = min(frame_width, image_width)
            max_height = min(frame_height, image_height)
        else:
            max_width = frame_width
            max_height = frame_height
        # Frame is wider than image.
        if frame_aspect > image_aspect:
            height = max_height
            width = int(height * image_aspect)
        # Frame is taller than image.
        else:
            width = max_width
            height = int(width / image_aspect)
        return (width, height)
    
    def stretchToFit(image, frame, enlarge=False):
        image_width, image_height = image
        frame_width, frame_height = frame
        # Stop image from being blown up.
        if not enlarge:
            width = min(frame_width, image_width)
            height = min(frame_height, image_height)
        else:
            width = frame_width
            height = frame_height
        return (width, height)
    
    
    class ResizableImage(gtk.DrawingArea):
    
        def __init__(self, aspect=True, enlarge=False,
                interp=gtk.gdk.INTERP_NEAREST, backcolor=None, max=(1600,1200)):
            """Construct a ResizableImage control.
    
            Parameters:
            aspect -- Maintain aspect ratio?
            enlarge -- Allow image to be scaled up?
            interp -- Method of interpolation to be used.
            backcolor -- Tuple (R, G, B) with values ranging from 0 to 1,
                or None for transparent.
            max -- Max dimensions for internal image (width, height).
    
            """
            super(ResizableImage, self).__init__()
            self.pixbuf = None
            self.aspect = aspect
            self.enlarge = enlarge
            self.interp = interp
            self.backcolor = backcolor
            self.max = max
            self.connect('expose_event', self.expose)
            self.connect('realize', self.on_realize)
    
        def on_realize(self, widget):
            if self.backcolor is None:
                color = gtk.gdk.Color()
            else:
                color = gtk.gdk.Color(*self.backcolor)
    
            self.window.set_background(color)
    
        def expose(self, widget, event):
            # Load Cairo drawing context.
            self.context = self.window.cairo_create()
            # Set a clip region.
            self.context.rectangle(
                event.area.x, event.area.y,
                event.area.width, event.area.height)
            self.context.clip()
            # Render image.
            self.draw(self.context)
            return False
    
        def draw(self, context):
            # Get dimensions.
            rect = self.get_allocation()
            x, y = rect.x, rect.y
            # Remove parent offset, if any.
            parent = self.get_parent()
            if parent:
                offset = parent.get_allocation()
                x -= offset.x
                y -= offset.y
            # Fill background color.
            if self.backcolor:
                context.rectangle(x, y, rect.width, rect.height)
                context.set_source_rgb(*self.backcolor)
                context.fill_preserve()
            # Check if there is an image.
            if not self.pixbuf:
                return
            width, height = resizeToFit(
                (self.pixbuf.get_width(), self.pixbuf.get_height()),
                (rect.width, rect.height),
                self.aspect,
                self.enlarge)
            x = x + (rect.width - width) / 2
            y = y + (rect.height - height) / 2
            context.set_source_pixbuf(
                self.pixbuf.scale_simple(width, height, self.interp), x, y)
            context.paint()
    
        def set_from_pixbuf(self, pixbuf):
            width, height = pixbuf.get_width(), pixbuf.get_height()
            # Limit size of internal pixbuf to increase speed.
            if not self.max or (width < self.max[0] and height < self.max[1]):
                self.pixbuf = pixbuf
            else:
                width, height = resizeToFit((width, height), self.max)
                self.pixbuf = pixbuf.scale_simple(
                    width, height,
                    gtk.gdk.INTERP_BILINEAR)
            self.invalidate()
    
        def set_from_file(self, filename):
            self.set_from_pixbuf(gtk.gdk.pixbuf_new_from_file(filename))
    
        def invalidate(self):
            self.queue_draw()
    
    class DemoGtk:
    
        SECONDS_BETWEEN_PICTURES = 3
        FULLSCREEN = True
        WALK_INSTEAD_LISTDIR = True
    
        def __init__(self):
            self.window = gtk.Window()
            self.window.connect('destroy', gtk.main_quit)
            self.window.set_title('Slideshow')
    
            self.image = ResizableImage( True, True, gtk.gdk.INTERP_BILINEAR)
            self.image.show()
            self.window.add(self.image)
    
            self.load_file_list()
    
            self.window.show_all()
    
            if self.FULLSCREEN:
                self.window.fullscreen()
    
            glib.timeout_add_seconds(self.SECONDS_BETWEEN_PICTURES, self.on_tick)
            self.display()
    
        def load_file_list(self):
            """ Find all images """
            self.files = []
            self.index = 0
    
            if self.WALK_INSTEAD_LISTDIR:
                for directory, sub_directories, files in os.walk('.'):
                    for filename in files:
                        if is_image(filename):
                            filepath = os.path.join(directory, filename)
                            self.files.append(filepath)
            else:
                for filename in os.listdir('.'):
                    if is_image(filename):
                        self.files.append(filename)
    
            print "Images:", self.files
    
        def display(self):
            """ Sent a request to change picture if it is possible """
            if 0 <= self.index < len(self.files):
                self.image.set_from_file(self.files[self.index])
                return True
            else:
                return False
    
        def on_tick(self):
            """ Skip to another picture.
    
            If this picture is last, go to the first one. """
            self.index += 1
            if self.index >= len(self.files):
                self.index = 0
    
            return self.display()
    
    if __name__ == "__main__":
        gui = DemoGtk()
        gtk.main()
    
    # vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
    

    【讨论】:

      【解决方案2】:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多