python-pillow / python-pillow/Pillow
quantize() reduces to far fewer colors than requested in some cases
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 13.8k
- Forks
- 2.5k
- Avg merge
- 2d 8h
- Merged PRs (30d)
- 89
Description
What did you do?
This image, named test-in.png, has 508 distinct colors according to getcolors().

I tried to quantize it to 256 colors with the following code.
from PIL import Image
MAXCOLORCOUNT = 1024
with Image.open("test-in.png") as im:
colsbefore = im.getcolors(maxcolors=MAXCOLORCOUNT)
colsbefore = len(colsbefore) if colsbefore is not None else f"{MAXCOLORCOUNT}<"
im = im.quantize(colors=256)
colsafter = len(im.getcolors(maxcolors=MAXCOLORCOUNT))
print(f"colors {colsbefore} -> {colsafter}")
im.save("test-out.png")
What did you expect to happen?
Reduced to 256 colors, i.e. print colors 508 -> 256
What actually happened?
Reduced to only 25 colors, i.e. prints colors 508 -> 25
What are your OS, Python and Pillow versions?
- OS: Ubuntu 20.04 (Kubuntu)
- Python: 3.9.1 (via pyenv)
- Pillow: 8.1.0
Other remarks
I'm guessing it's something about the image having only a few distinct RGB values but with a wide range of alpha values. A test image with over 256 distinct RGB values had no such issue.
Why don't I use pngquant or imagemagick instead? I depend on Pillow because I need a quantization method that preserves the colors of fully transparent pixels. (I'm modding a game whose texture filtering causes the colors of fully-transparent pixels to be faintly but noticeably visible around the edges of the fully-transparent regions.)
Edit: Using im.convert("P") on an image that already has 256 or fewer colors (according to len(im.getcolors())) can cause it to lose more colors unnecessarily during the conversion.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the reported result with test-in.png and the Python quantize() call described in the issue. Trace the quantization entry point and its handling of RGB values with varying alpha, then add a regression test for the 508-color image. Done means quantizing this case no longer unexpectedly produces only 25 colors and the existing test suite still passes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- computer-vision
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100