【问题标题】:How can I save an image with PIL?如何使用 PIL 保存图像?
【发布时间】:2013-01-05 08:16:50
【问题描述】:

我刚刚使用 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'

如何使用 Pythons PIL 保存图像?

【问题讨论】:

    标签: python save python-imaging-library


    【解决方案1】:

    已处理有关文件扩展名的错误,您可以使用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')
    

    【讨论】:

    • 嘿,非常感谢。它现在完美无缺!现在我所要做的就是了解所有步骤,但这不会太糟糕。非常感谢您的帮助
    • @user1999274 主要区别在于使用fft2 而不是rfft2,因为对于离散数据,我看不到使用后者的意义。其余的纯粹是装饰性的,即,如果不对其应用对数因子,您将无法正确可视化傅立叶变换。然后归一化是为了使转换到范围 [0, 255] 时保持简单。
    • visual = (visual - visual.min()) / (visual.max() - visual.min()) 将默认,如果 visual 没有变化(不太可能,但值得抓住)
    • 我尝试使用此代码解决我的问题,但我得到纯黑色图像。有人对此有任何想法吗? stackoverflow.com/questions/24266000/…
    【解决方案2】:

    我知道这是旧的,但我发现(在使用 Pillow 时)使用 open(fp, 'w') 打开文件然后保存文件会起作用。例如:

    with open(fp, 'w') as f:
        result.save(f)
    

    fp 当然是文件路径。

    【讨论】:

    • Pillow 的documentation 表示,如果在save 中使用文件对象,则应使用format 参数。这没有必要吗?
    • @RobRose 在我的测试过程中,当我发布答案时,我没有发现任何类似的必要。但是,现在可能是这样。如果您进行的任何测试证明有必要,请告诉我,我将编辑我的答案
    • 存储字节的模式应该是'wb'
    【解决方案3】:

    尝试删除.bmp 之前的.(它与预期的BMP 不匹配)。从错误中可以看出,save_handler 将您提供的format 大写,然后在SAVE 中寻找匹配项。但是该对象中的对应键是BMP(而不是.BMP)。

    我对@9​​87654330@ 了解不多,但通过一些快速搜索,似乎是图像的mode 有问题。将j的定义更改为:

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

    似乎对我有用(但请注意,我对PIL 知之甚少,所以我建议使用@mmgp 的解决方案,因为他/她清楚地知道他们在做什么:))。对于mode 的类型,我使用了this 页面——希望其中的一种选择对你有用。

    【讨论】:

    • 我尝试删除 .bmp 以支持 bmp,但它仍然没有工作。我现在得到的错误是:IOError:无法将模式 F 写入 BMP。我检查了 PIL 页面的文档,它说要使用 .bmp,所以总的来说我仍然不知道它为什么不起作用。
    • @user1999274 发布了一个似乎对我有用的更新(为缺乏细节道歉 - 我继续拼凑起来:))。
    • @RocketDonkey 它比这更聪明一些,因为将傅里叶变换的结果转换为 RGB 颜色空间会产生毫无意义的图像。仅仅因为它不再引发异常,并不意味着结果是正确的。
    • @mmgp 同意 - 这就是为什么我 +1 你的,希望 OP 接受它:)
    【解决方案4】:

    您应该能够简单地让 PIL 从扩展名中获取文件类型,即使用:

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

    【讨论】:

    • 感谢您的意见。但是,当我尝试让保存功能像您上面建议的那样获取文件类型时,我收到以下错误:IOError:无法将模式 F 写入 BMP。有什么建议吗?
    • 是的,您应该将数组转换为numpy.uint8 dtype 而不是float。
    猜你喜欢
    • 2013-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-21
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多