使用wxPython显示缩略图的简单方法

时间:2014-03-16 23:12:21

标签: python wxpython wxwidgets

我正在寻找一个使用wxPython显示缩略图的简单解决方案。这与创建缩略图无关。我有一个缩略图目录,想要在屏幕上显示它们。我故意不使用像(Panel,Frame,Window,ScrolledWindow)这样的术语,因为我对各种解决方案持开放态度。

另请注意,我找到了多个显示单个图像的示例,因此引用任何此类解决方案都无济于事。解决方案必须是在wx中同时显示多个图像。

似乎我想要做的是在ThumbnailCtrl中完成,但Andrea的代码很复杂,我无法找到显示屏幕的部分。我确实在Mark Lutz的Programming Python书中找到了一个简单的解决方案,但是他的viewer_thumbs.py示例肯定具有我想要的简单性,它是使用Tkinter完成的。

所以请非常感谢任何wx解决方案。

编辑:我正在添加一个链接到一个可以找到Mark Lutz工作Tkinter代码的地方。谁能想到wx等价物?

http://codeidol.com/community/python/viewing-and-processing-images-with-pil/17565/#part-33

3 个答案:

答案 0 :(得分:2)

我建议使用ThumbNailCtrl小部件:http://wxpython.org/Phoenix/docs/html/lib.agw.thumbnailctrl.html。 wxPython演示中有一个很好的例子。或者你可以从文档中使用这个。请注意,ThumbNailCtrl需要安装Python Imaging Library。

import os

import wx
import wx.lib.agw.thumbnailctrl as TC

class MyFrame(wx.Frame):

    def __init__(self, parent):

        wx.Frame.__init__(self, parent, -1, "ThumbnailCtrl Demo")

        panel = wx.Panel(self)

        sizer = wx.BoxSizer(wx.VERTICAL)

        thumbnail = TC.ThumbnailCtrl(panel, imagehandler=TC.NativeImageHandler)
        sizer.Add(thumbnail, 1, wx.EXPAND | wx.ALL, 10)

        thumbnail.ShowDir(os.getcwd())
        panel.SetSizer(sizer)


# our normal wxApp-derived class, as usual

app = wx.App(0)

frame = MyFrame(None)
app.SetTopWindow(frame)
frame.Show()

app.MainLoop()

只需更改 thumbnail.ShowDir(os.getcwd())一行,使其指向计算机上的右侧文件夹。

我还在这里写了一篇文章来查看照片:http://www.blog.pythonlibrary.org/2010/03/26/creating-a-simple-photo-viewer-with-wxpython/它虽然没有使用缩略图。

答案 1 :(得分:2)

不确定我是否应该回答我自己的问题,但我确实找到了解决问题的方法,我想分享。我使用的是wx版本2.8。我发现在2.9和3.0中添加了一个名为WrapSizer的小部件。一旦我将我的wx版本更新为3.0,使得解决方案变得简单。以下是重要的代码片段。

    self.PhotoMaxWidth = 100
    self.PhotoMaxHeight = 100

    self.GroupOfThumbnailsSizer = wx.WrapSizer()      

    self.CreateThumbNails(len(ListOfPhotots),ListOfPhotots)

    self.GroupOfThumbnailsSizer.SetSizeHints(self.whateverPanel) 
    self.whateverPanel.SetSizer(self.GroupOfThumbnailsSizer)

    self.whateverPanel.Layout()


def CreateThumbNails(self, n, ListOfFiles):
    thumbnails = []
    backgroundcolor = "white"

    for i in range(n):

        ThumbnailSizer = wx.BoxSizer(wx.VERTICAL)
        self.GroupOfThumbnailsSizer.Add(ThumbnailSizer, 0, 0, 0)
        thumbnails.append(ThumbnailSizer)

    for thumbnailcounter, thumbsizer in enumerate(thumbnails):

        image = Image.open(ListOfFiles[thumbnailcounter])

        image = self.ResizeAndCenterImage(image, self.PhotoMaxWidth, self.PhotoMaxHeight, backgroundcolor)

        img = self.pil_to_image(image)

        thumb= wx.StaticBitmap(self.timelinePanel, wx.ID_ANY, wx.BitmapFromImage(img))

        thumbsizer.Add(thumb, 0, wx.ALL, 5)

    return

def pil_to_image(self, pil, alpha=True):
    """ Method will convert PIL Image to wx.Image """
    if alpha:
        image = apply( wx.EmptyImage, pil.size )
        image.SetData( pil.convert( "RGB").tostring() )
        image.SetAlphaData(pil.convert("RGBA").tostring()[3::4])
    else:
        image = wx.EmptyImage(pil.size[0], pil.size[1])
        new_image = pil.convert('RGB')
        data = new_image.tostring()
        image.SetData(data)
    return image

def ResizeAndCenterImage(self, image, NewWidth, NewHeight, backgroundcolor):
    width_ratio = NewWidth / float(image.size[0])
    temp_height = int(image.size[1] * width_ratio)
    if temp_height < NewHeight:
        img2 = image.resize((NewWidth, temp_height), Image.ANTIALIAS)
    else:
        height_ratio = NewHeight / float(image.size[1])
        temp_width = int(image.size[0] * height_ratio)
        img2 = image.resize((temp_width, NewHeight), Image.ANTIALIAS)

    background = Image.new("RGB", (NewWidth, NewHeight), backgroundcolor)
    masterwidth = background.size[0]
    masterheight = background.size[1]
    subwidth = img2.size[0]
    subheight = img2.size[1]
    mastercenterwidth = masterwidth // 2
    mastercenterheight = masterheight // 2
    subcenterwidth = subwidth // 2
    subcenterheight = subheight // 2
    insertpointwidth = mastercenterwidth - subcenterwidth
    insertpointheight = mastercenterheight - subcenterheight
    background.paste(img2, (insertpointwidth, insertpointheight))

    return background

我从另一个stackoverflow帖子中得到了pil_to_image部分,我编写了ResizeAndCenterImage部分,使我的所有缩略图都保持相同的大小,同时保持纵横比不变,不进行任何裁剪。如果您愿意,可以一起跳过调整大小和中心调用。

答案 2 :(得分:0)

我只是将它们显示为框架内的wx.Image。

http://www.wxpython.org/docs/api/wx.Image-class.html

来自类:“独立于平台的图像类。可以从数据创建图像,也可以使用wx.Bitmap.ConvertToImage创建图像,或者从各种格式的文件加载图像。可以使用函数来设置和获取图像位,所以它可以用于基本的图像处理。“

似乎它应该能够做你想要的,除非我遗漏了什么。