gpt4 book ai didi

python - wxPython图像占用大量内存

转载 作者:行者123 更新时间:2023-12-01 03:33:21 27 4
gpt4 key购买 nike

我有一个数据项目,它会在不同的目录中生成许多具有相同名称的图。查看这些图有助于了解数据是否发生了任何奇怪的情况,但是尝试将它们全部打开或将它们全部复制到一个目录,重命名它们,然后打开我的标准图像将是一件痛苦的事情查看器。

了解一些 wxPython GUI 编程后,我决定开发一个应用程序,该应用程序将接收这些图像的目录列表,并且我可以使用一些箭头按钮幻灯片显示它们。然后,随着更多绘图的出现,我可以将其添加到此列表中。

我的应用程序运行正常,但现在当我加载大约 23 ~3 MB 的图像时,我的程序内存使用量接近 10 GB。

代码如下,但简而言之,我在显示之前将它们全部加载为 wxPython 图像,这就是内存攀升的地方。通过堆栈在图像之间切换似乎不会使内存进一步攀升。我认为可能是我保留了不再需要的资源,但使用情况似乎与图像的大小和数量不成比例。

有人能指出我方法中的缺陷吗?

```

class Slide(wx.Frame):

def __init__(self):
wx.Frame.__init__(self, None, -1, "Slide Show")

self.display = wx.GetDisplaySize()

self.image_list = None
self.current = None # holds currently displayed bitmap
# stacks that hold the bitmaps
self.future = []
self.past = []


self.left = wx.BitmapButton(self, id=101, size=(100,-1), bitmap=wx.ArtProvider.GetBitmap(wx.ART_GO_BACK))
self.left.Enable(False)
self.right = wx.BitmapButton(self, id=102, size=(100,-1), bitmap=wx.ArtProvider.GetBitmap(wx.ART_GO_FORWARD))
self.right.Enable(False)
self.open = wx.BitmapButton(self, id=103, size=(100,-1), bitmap=wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN))

# Testing code
#png = wx.Image("set001_fit_001_1.png", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
#image = wx.ImageFromBitmap(png)
#image = image.Scale(self.display[0]/1.4, self.display[1]/1.4, wx.IMAGE_QUALITY_HIGH)
#png = wx.BitmapFromImage(image)

# make empty image slot
self.img = wx.StaticBitmap(self, -1, size=(self.display[0]/1.4, self.display[1]/1.4))


## Main sizers
self.vertSizer = wx.BoxSizer(wx.VERTICAL)

# sub sizers
self.buttonSizer = wx.BoxSizer(wx.HORIZONTAL)

# place buttons together
self.buttonSizer.Add(self.left, flag=wx.ALIGN_CENTER)
als.AddLinearSpacer(self.buttonSizer, 15)
self.buttonSizer.Add(self.right, flag=wx.ALIGN_CENTER)

# place arrows and open together
self.vertSizer.Add(self.img, flag=wx.ALIGN_CENTER)
self.vertSizer.Add(self.open, flag=wx.ALIGN_CENTER)
als.AddLinearSpacer(self.vertSizer, 15)
self.vertSizer.Add(self.buttonSizer, flag=wx.ALIGN_CENTER)
als.AddLinearSpacer(self.vertSizer, 15)

self.Bind(wx.EVT_BUTTON, self.onOpen, id=103)
self.Bind(wx.EVT_BUTTON, self.onLeft, id=101)
self.Bind(wx.EVT_BUTTON, self.onRight, id=102)

self.SetSizer(self.vertSizer)
self.vertSizer.Fit(self)

def onOpen(self, evt):
print("Opening")
openFileDialog = wx.FileDialog(self, "Open Image List", "", "", "List (*.ls)|*.ls", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
if openFileDialog.ShowModal() == wx.ID_CANCEL:
return

fileName = str(openFileDialog.GetPath())
print(fileName)

# put image list in a python list
image_list = []
f = open(fileName, 'r')
for line in f:
image_list.append(line.rstrip())
f.close()

print(image_list)
# convert every image to wx Image
png_list = []
for image in image_list:
png = wx.Image(image, wx.BITMAP_TYPE_ANY)
png_list.append(png)

# store pngs
print(image_list[::-1])
png_list = png_list[::-1]
for png in png_list[:-1]:
self.future.append(png)

# display first png
self.current = png_list[-1] # put into current buffer
png = self.current.Scale(self.display[0]/1.4, self.display[1]/1.4, wx.IMAGE_QUALITY_HIGH)
png = wx.BitmapFromImage(png)
self.img.SetBitmap(png)

self.Refresh()
self.right.Enable(True)

def onLeft(self, evt):
# put current image into future stack and grab a new current image from past stack
self.future.append(self.current)
self.current = self.past.pop()

png = self.current.Scale(self.display[0]/1.4, self.display[1]/1.4, wx.IMAGE_QUALITY_HIGH)
png = wx.BitmapFromImage(png)
self.img.SetBitmap(png)
self.Refresh()
if len(self.past) <= 0:
self.left.Enable(False)

self.right.Enable(True)

def onRight(self, evt):
# put current image into past stack and load in a new image from future stack
self.past.append(self.current)
self.current = self.future.pop()

png = self.current.Scale(self.display[0]/1.4, self.display[1]/1.4, wx.IMAGE_QUALITY_HIGH)
png = wx.BitmapFromImage(png)
self.img.SetBitmap(png)
self.Refresh()

if len(self.future) <= 0:
self.right.Enable(False)
self.left.Enable(True)

```

最佳答案

根据需要加载它们可能是减少内存使用的最佳方法。或者也许将当前、下一个和上一个图像保留在内存中以帮助加快 View 之间的切换。或者可以使用缓存实现将N 最近查看的图像(加上序列中的下一个图像)保留在内存中。然后,您可以调整 N 的大小,看看什么效果最好,并且是内存和速度之间的合理折衷。

另一个可能的改进是不在每次需要显示图像时缩放图像,只需在读取图像时缩放一次并将其保留在内存(或缓存)中。您可能还想尝试将它们预先转换为 wx.Bitmaps,因为图像到位图的转换并不是一个简单的操作。

关于python - wxPython图像占用大量内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40622028/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com