Search code examples
pythonpython-imaging-library

"ValueError: cannot allocate more than 256 colors" when using ImageDraw.Draw()


I have the following code:

def draw():
    img = Image.open(image)
    draw = ImageDraw.Draw(img)
    font = ImageFont.truetype("Poppins-Thin.ttf", 20)
    watermark_text = "some text"
    draw.text((0, img.height - 25), watermark_text, (211, 211, 211), font=font)
    return img

It works with some images, but some throw a ValueError: cannot allocate more than 256 colors error. Manipulating a failing image works without the draw function (I am resizing and compressing it).

How can I have it work for all supported images?

Working image example.

Failing image example.


Solution

  • This image uses indexed-colors (it keeps RGB colors on list and every pixel has only index to this color) and it may use only 256 indexes. This way file is smaller, it uses less memory RAM and less space on disk, and web page can load it faster - so users don't resign to visit page (and server sends less bytes so it costs less)

    You have to convert to RGB (or RGBA if you whan to keep transparent background)

    img = img.convert('RGBA')
    

    Eventually you can use index to some color (ie. 221) instead of tuple (R,G,B) in

    draw.text((0, img.height - 25), watermark_text, 211)
    

    but it makes problem to recognize what color it will give on image.


    You can detect type of pallete (mode) with

    print(img.mode)
    

    and here explanations