我正在寻找一个使用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
答案 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创建图像,或者从各种格式的文件加载图像。可以使用函数来设置和获取图像位,所以它可以用于基本的图像处理。“
似乎它应该能够做你想要的,除非我遗漏了什么。