Velvet Star Monitor

Standout celebrity highlights with iconic style.

updates

PIL cannot write mode F to jpeg

Writer Emily Wong

I am taking a jpg image and using numpy's fft2 to create/save a new image. However it throws this error

"IOError: cannot write mode F as JPEG" 

Is there an issue with CMYK and JPEG files in PIL???

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()

6 Answers

Try convert the image to RGB:

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

Semente's answer is right for color images For grayscale images you can use below:-

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

If you use new_p = new_p.convert('RGB') for a grayscale image then the image will still have 24 bit depth instead of 8 bit and would occupy thrice the size on hard disk and it wont be a true grayscale image.

1

I think it may be that your fft_p array is in float type and the image should have every pixel in the format 0-255 (which is uint8), so maybe you can try doing this before creating the image from array:

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

But be aware that every element in the fft_p array should be in the 0-255 range, so maybe you would need to do some processing to that before to get the desired results, for example if you every element is a float between 0 and 1 you can multiply them by 255.

2
def save_img(img, path): img = Image.fromarray(img) img.save(path)
raise OSError(f"cannot write mode {mode} as PNG") from e

OSError: cannot write mode F as PNG

Here the meaning of mode F is the floating point value in the image. So please convert the floating point image to the uint8 image before saving.

image.astype(np.uint8)

If you are working with PyTorch

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

I had the same issue, but my image was a gray-scale one, consisting of only float numbers between 0 and 1. I was able to save my image with the original data through the following method:

import PIL as pillow, numpy
# Normalize the image with values between 0 and 255
normalized_image = (final_image - numpy.min(final_image)) * (255.0 / (numpy.max(final_image) - numpy.min(final_image)))
normalized_image = normalized_image.astype('uint8')
# Convert the normalized numpy array to an image using Pillow
image = pillow.Image.fromarray(normalized_image)
# Save the final image
image.save('image.png')

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.