I am processing images with PIL. When I open and convert some images to RGBA they get completely deteriorated.
One example of such an image is the following one:

$ file input_image.png
input_image.png: PNG image data, 502 x 1180, 16-bit grayscale, non-interlaced
After the conversion I get the following:

I run the following code.
from PIL import Image
img = Image.open("input_image.png")
img_rgba = img.convert("RGBA")
img_rgba.save("output_image.png")
I would expect that the output image looks like the input image.
Your original image is a 16-bit greyscale image. You can see that if you print the image:
im = Image.open(...)
print(im)
You'll see it is in I mode, i.e. 32-bit because that's what PIL uses for 16-bit images.
<PIL.PngImagePlugin.PngImageFile image mode=I size=502x1180>
You can also see that with exiftool, if you run:
exiftool YOURIMAGE
When you convert it to RGBA mode, PIL makes it into RGBA8888 - i.e. 4 channels of 8 bits each and you lose data.
If you want to convert from GREY16 to RGBA8888 with solid blacks and whites, you need to rescale to range 0..255 like this:
from PIL import Image
import numpy as np
# Open 16-bit image and make Numpy array version
im = Image.open('image.png')
na = np.array(im)
# Rescale to range 0..255
res = (na - na.min())*255/(na.max()-na.min())
# Make back into uint8 PIL Image
pi = Image.fromarray(res.astype(np.uint8))
# Convert to RGBA8888
pi = pi.convert('RGBA')
pi.save('result.png')

PIL opening 16-bit grayscale PNG images as 32-bit, is a known issue.
But that's not the only problem. Even first converting it to I;16 mode (with .convert("I;16"), won't work, since PIL won't properly scale the grayscale values to RGB either way.
You can scale the values with the .point method.
Assuming you will read images in other formats, you should do a check, if it needs this fix.
img = Image.open(input_image)
if (img.format == "PNG" and img.mode == "I") or img.mode == "I;16":
img = img.point(lambda p: p * (1 / 256))
img_rgba = img.convert("RGBA")
img_rgba.save(output_image)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With