我该如何用PIL保存图像?

159 投票
5 回答
463663 浏览
提问于 2025-04-17 13:20

我刚刚使用Python的图像库(PIL)做了一些图像处理,参考了一篇文章来对图像进行傅里叶变换,但我无法让保存功能正常工作。整个代码运行得很好,但就是无法保存处理后的图像:

from PIL import Image
import numpy as np

i = Image.open("C:/Users/User/Desktop/mesh.bmp")
i = i.convert("L")
a = np.asarray(i)
b = np.abs(np.fft.rfft2(a))
j = Image.fromarray(b)
j.save("C:/Users/User/Desktop/mesh_trans",".bmp")

我遇到的错误是:

save_handler = SAVE[string.upper(format)] # unknown format
    KeyError: '.BMP'

我该如何用Python的PIL保存一张图像呢?

5 个回答

6

试着把 .bmp 前面的 . 去掉(因为它没有像预期那样匹配 BMP)。从错误信息来看,save_handler 把你提供的 format 转成了大写,然后在 SAVE 中寻找匹配项。不过在那个对象里对应的键是 BMP(而不是 .BMP)。

我对 PIL 了解不多,但我快速查了一下,似乎这是和图像的 mode 有关。把 j 的定义改成:

j = Image.fromarray(b, mode='RGB')

对我来说似乎有效(不过请注意,我对 PIL 知之甚少,所以我建议你使用 @mmgp 的解决方案,因为他/她显然知道自己在做什么 :))。关于 mode 的类型,我参考了 这个页面——希望那里的某个选项能对你有帮助。

42

你可以直接让PIL根据文件的扩展名来识别文件类型,也就是说,你可以这样使用:

j.save("C:/Users/User/Desktop/mesh_trans.bmp")
189

关于文件扩展名的错误已经解决,你可以使用 BMP(记得不要加点)或者直接把输出文件名带上扩展名。现在,要处理这个错误,你需要正确修改你的数据,使其在频率域中能够保存为整数图像,PIL 提示你,它不接受浮点数据来保存为 BMP 格式。

这里有一个建议(还有其他一些小修改,比如使用 fftshiftnumpy.array 代替 numpy.asarray)来进行转换,以便更好地可视化:

import sys
import numpy
from PIL import Image

img = Image.open(sys.argv[1]).convert('L')

im = numpy.array(img)
fft_mag = numpy.abs(numpy.fft.fftshift(numpy.fft.fft2(im)))

visual = numpy.log(fft_mag)
visual = (visual - visual.min()) / (visual.max() - visual.min())

result = Image.fromarray((visual * 255).astype(numpy.uint8))
result.save('out.bmp')

撰写回答