Reputation: 5780
I have an RGB
image with only 25 colors,
and I want to convert it to P
mode to make it indexed (saving space, as far as I understand), but the resulting image, though in P
mode and indexed, has got 70 colors instead of 25:
>>> from PIL import Image
>>> img = Image.open(r"test_rgb2p.png")
>>> img.mode
'RGB'
>>> len(img.getcolors())
25
>>> img = img.convert(mode='P')
>>> img.mode
'P'
>>> len(img.getcolors())
70
I guess that the convert
command performs some kind of unnecessary resampling, because I see no reason why the number of colors should increment. In fact with GIMP I'm able to convert this same image to indexed colors and the number of colors does not change.
Is there a way to do this RGB
to P
mode conversion without changes in colors?
Upvotes: 2
Views: 1131
Reputation: 308111
Pillow has no idea that the number of colors in your image is restricted, so it must invent a palette that it thinks can handle everything. You'll probably find that nearly none of those 70 colors is exactly identical to the colors in your image.
In fact if you look at the documentation for Image.convert
you'll see that it defaults to a web palette. If you add palette=ADAPTIVE
it might give better results:
img = img.convert(mode='P', palette=Image.Palette.ADAPTIVE)
Older versions of PIL/Pillow didn't have the Palette
enumeration (I used 8.1.0 for this answer) and the constant is part of Image
itself:
img = img.convert(mode='P', palette=Image.ADAPTIVE)
Upvotes: 1
Reputation: 1472
You could try
# Quantize the image to reduce the number of colors to 25
img = img.quantize(colors=25)
# Convert the image to P mode
img = img.convert(mode='P')
# Check the number of colors in the image
print(len(img.getcolors())) # should print 25
This worked great for me at least!
Upvotes: 0