使用临时文件作为 wxPython 图像小部件的源

Using tempfile as source for wxPython image widget

我正在使用 pyplot.savefig 将 matplotlib 图保存为 .png 并且此代码有效:

pyplot.savefig('tempfile.png', bbox_inches='tight', pad_inches=0.0)
i = wx.Image('tempfile.png', 'image/png', -1)
i.Resize(size=(500,500), pos=(0,0), red=255, green=255, blue=255)
png = i.ConvertToBitmap()
self.xrayImage = wx.StaticBitmap(self.panel, -1, png, (380,10), (500,500))

我不想让这个 tempfile.png 在程序执行后仍然存在,理想情况下它甚至不会出现在用户环境中。我一直在尝试使用 python 的临时文件功能,但总是从 i.Resize 行获取无效图像,或者不是 .png 图像。我试过使用 tempfile.TemporaryFile 和 tempfile.NamedTemporaryFile 但都没有用。这是我尝试过的一些示例:

temp_png = tempfile.NamedTemporaryFile(suffix='.png')
pyplot.savefig(temp_png)
i.wx.Image(temp_png, 'image/png', -1)
i.Resize(size=(500,500), pos=(0,0), red=255, green=255, blue=255)
png = i.ConvertToBitmap()
self.xrayImage = wx.StaticBitmap(self.panel, -1, png, (380,10), (500,500))

和:

with tempfile.TemporaryFile(suffix=".png") as tmpfile:
    pyplot.savefig(tmpfile)
    tmpfile.seek(0)
    i = wx.Image(tmpfile, 'image/png', -1)
    # also tried:
    # i = wx.Image(tmpfile.read(), 'image/png', -1)
    # i = wx.Image(b64encode(tmpfile.read()), 'image/png', -1)
    i.Resize(size=(500,500), pos=(0,0), red=255, green=255, blue=255)
png = i.ConvertToBitmap()
self.xrayImage = wx.StaticBitmap(self.panel, -1, png, (380,10), (500,500))

如有任何帮助,我们将不胜感激!只要用户计算机上没有文件,我也愿意不使用 python 的临时文件。

为什么不在显示图像文件后就将其删除?

import wx
import os
import matplotlib
matplotlib.use('agg')
from matplotlib import pyplot as plt

class TestFrame(wx.Frame):
    def __init__(self, *args):
        wx.Frame.__init__(self, *args)
        plt.plot([1.5,2.0,2.5])
        fig = plt.gcf()
        fig.savefig("/tmp/myimg.png", transparent=True)
        aText = wx.StaticText(self,-1,("My Image Display"))
        img = wx.Image("/tmp/myimg.png", wx.BITMAP_TYPE_ANY)
        Image = wx.StaticBitmap(self, bitmap=wx.BitmapFromImage(img))
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(aText,0,0,0)
        sizer.Add(Image,1,0,0)
        self.SetSizer(sizer)
        self.Fit()
        self.Show()
        os.remove("/tmp/myimg.png")

if __name__ == "__main__":
    app = wx.App()
    myframe = TestFrame(None, -1, "Image Test")
    app.MainLoop()

根据用户 ImportanceOfBeingEarnest 的建议:完全摆脱临时文件并使用缓冲区存储 savefig 的结果(使用 wxPython 4.0.1 测试)

import wx

from io import BytesIO
from matplotlib import pyplot as plt
from matplotlib import rc

def get_pyplot_img():
    rc('savefig', format='png')
    buf = BytesIO()
    plt.plot([0, 1, 2], [0, 1, 4], '-')
    plt.savefig(buf)
    # reset buf pointer
    buf.seek(0)
    return buf

def get_bitmap(buf):
    img = wx.Image(buf, wx.BITMAP_TYPE_PNG)
    return wx.Bitmap(img)

我在尝试将 wx.Bitmap 保存到使用 tempfile.TemporaryFile 创建的临时文件时遇到了完全相同的问题。 wx.Bitmap.SaveFile() return 错误,我不知道为什么。

作为解决方法,我使用了一个临时文件夹并且它起作用了。大致如下:

with tempfile.TemporaryDirectory() as directory:
  success = image.SaveFile(directory + "\temp.png", wx.BITMAP_TYPE_PNG)
  if success:
    do_something_with_the_picture(directory + "\temp.png")