PIL无法将模式F写入JPEG

80

我正在使用numpy的fft2函数来处理一张jpg格式的图片并创建/保存一个新的图片。但是程序报错:

"IOError: cannot write mode F as JPEG" 

在PIL中,CMYK和JPEG文件是否存在问题?

p = Image.open('kibera.jpg')
bw_p = p.convert('L')
array_p = numpy.asarray(bw_p)
fft_p = abs(numpy.fft.rfft2(array_p))
new_p = Image.fromarray(fft_p)
new_p.save('kibera0.jpg')
new_p.histogram()
5个回答

80

尝试将图像转换为RGB:

...
new_p = Image.fromarray(fft_p)
if new_p.mode != 'RGB':
    new_p = new_p.convert('RGB')
...

20
如果一张图片是灰度的,会怎么样? - cerebrou
11
咚一声,如果我想保存成灰度图怎么办? - Hakaishin
4
可以直接使用这个。它在灰度模式下也能正常工作。 - Zeroth

51

对于彩色图像,Semente的答案是正确的。 对于灰度图像,您可以使用以下方法:

new_p = Image.fromarray(fft_p)
new_p = new_p.convert("L")

如果你对一张灰度图像使用 new_p = new_p.convert('RGB'),那么该图像仍将具有24位深度,而不是8位深度,它会占用三倍的硬盘空间,并且不会是真正的灰度图像。


2
有关“convert”的更多信息,请访问此处:https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.convert - Aaron Swan

20

我认为可能是您的fft_p数组是浮点型的,而图像应该以0-255(即uint8)格式的每个像素表示,因此在从数组创建图像之前,您可以尝试执行以下操作:

fft_p = fft_p.astype(np.uint8)
new_p = Image.fromarray(fft_p)

但要注意,fft_p 数组中的每个元素应该在 0-255 范围内,因此您可能需要在获取所需结果之前对其进行一些处理,例如,如果每个元素都是介于 0 和 1 之间的浮点数,则可以将它们乘以 255。


这是正确的答案,因为它不改变numpy数组的实际值(只改变类型格式)。 - Muhammad Yasirroni
非常有用的提示,应该使用 uint8。我试图在jupyter上预览mnist灰度数据时遇到了这个问题。正确的代码应该像这样:Image.fromarray((mnist_images[0]*255).astype(np.uint8)) - Kassian Sun

3
def save_img(img, path):

    img = Image.fromarray(img)

    img.save(path)

raise OSError(f"cannot write mode {mode} as PNG") from e

OSError: 无法将模式 F 写入 PNG。这里的模式 F 指图像中的浮点值。因此,请在保存之前将浮点图像转换为 uint8 图像。该错误提示您需要将浮点图像转换为整数类型再进行保存。
image.astype(np.uint8)

0

如果你正在使用PyTorch

import torchvision.transforms as T
    
        
transform=T.ToPILImage()
imt=transform(img)

1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接