如何将 Matplotlib 图转换为 PIL 图像对象(不保存图像)

新手上路,请多包涵

如标题所述,我正在尝试将 fig 转换为 PIL.Image 。我目前能够通过首先将 fig 保存到磁盘然后使用 Image.open() 打开该文件来做到这一点,但是这个过程花费的时间比预期的要长,我希望通过跳过保存本地步骤会快一点。

这是我到目前为止所拥有的:

 # build fig
figsize, dpi = self._calc_fig_size_res(img_height)
fig = plt.Figure(figsize=figsize)
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
ax.imshow(torch.from_numpy(S).flip(0), cmap = cmap)
fig.subplots_adjust(left = 0, right = 1, bottom = 0, top = 1)
ax.axis('tight'); ax.axis('off')

# export
fig.savefig(export_path, dpi = dpi)

# open image as PIL object
img = Image.open(export_path)

我在构建无花果后尝试这样做(就在导出阶段之前):

 pil_img = Image.frombytes('RGB', canvas.get_width_height(), canvas.tostring_rgb())

但它并没有显示整个图像。它看起来像是左上角的裁剪图,但它可能只是数据的一种奇怪表示形式——我正在处理频谱图,因此图像相当抽象。

原文由 Zach 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.5k
2 个回答

编辑#2

 PIL.Image.frombytes('RGB',
fig.canvas.get_width_height(),fig.canvas.tostring_rgb())

与下面的 3540 毫秒相比,大约需要 2 毫秒。

这是迄今为止我能找到的最快的方法。


我今天也一直在看这个。

在 matplotlib 文档中,savefig 函数有这个。

pil_kwargsdict,可选 保存图形时传递给 PIL.Image.save 的附加关键字参数。仅适用于使用 Pillow 保存的格式,即 JPEG、TIFF 和(如果关键字设置为非 None 值)PNG。

这一定意味着它在保存之前已经是一个 pil 图像,但我看不到它。

你可以按照这个

Matplotlib:将绘图保存到 numpy 数组

把它放到一个 numpy 数组中然后做

PIL.Image.fromarray(array)

您可能需要使用数组将通道从 BGR 反转为 RGB [:, :, ::-1]

编辑:

到目前为止,我已经测试了每种方法。

 import io

def save_plot_and_get():
    fig.savefig("test.jpg")
    img = cv2.imread("test.jpg")
    return PIL.Image.fromarray(img)

def buffer_plot_and_get():
    buf = io.BytesIO()
    fig.savefig(buf)
    buf.seek(0)
    return PIL.Image.open(buf)

def from_canvas():
    lst = list(fig.canvas.get_width_height())
    lst.append(3)
    return PIL.Image.fromarray(np.fromstring(fig.canvas.tostring_rgb(),dtype=np.uint8).reshape(lst))

结果

%timeit save_plot_and_get()

每个循环 35.5 毫秒 ± 148 µs(7 次运行的平均值 ± 标准偏差,每次 10 次循环)

 %timeit save_plot_and_get()

每个循环 35.5 毫秒 ± 142 µs(7 次运行的平均值 ± 标准偏差,每次 10 次循环)

 %timeit buffer_plot_and_get()

每个循环 40.4 毫秒 ± 152 µs(7 次运行的平均值 ± 标准偏差,每次 10 次循环)

原文由 Lewis Morris 发布,翻译遵循 CC BY-SA 4.0 许可协议

我使用以下功能:

 def fig2img(fig):
    """Convert a Matplotlib figure to a PIL Image and return it"""
    import io
    buf = io.BytesIO()
    fig.savefig(buf)
    buf.seek(0)
    img = Image.open(buf)
    return img

用法示例:

 import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

x = np.arange(-3,3)
plt.plot(x)
fig = plt.gcf()

img = fig2img(fig)

img.show()

原文由 kotchwane 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题