Home > Net >  Paint everything outside of polygons in a Pillow image in palette mode?
Paint everything outside of polygons in a Pillow image in palette mode?

Time:06-29

I'm creating a heatmap using Pillow in Python. After painting the heatmap, I want to blank out everything outside a certain area. The area in question is described by a handful of polygons, each containing a couple of thousands of points.

I know how to paint everything inside the polygons (see below), but how do I paint everything outside the polygons? The below examples paints the polygons blue, while it keeps the color of the background. I want to paint the bakground blue, while keeping the color of the polygons.

from PIL import Image, ImageDraw


# This image painted red represents the heatmap.
# In reality, it's not a solid color but the result of some calculations.
image = Image.new("P", (500, 500), 1)
image.putpalette([
    0, 0, 255,
    255, 0, 0
])
draw = ImageDraw.Draw(image)

# Actual polygon is much more complex.
polygons = [[(100, 100), (100, 400), (350, 50)], [(150, 450), (400, 300), (450, 50)]]

# This is the opposite of what I want. It paints everything in the polygons blue.
# I want everything outside of them blue.
for polygon in polygons:
    draw.polygon(polygon, fill=0, outline=None, width=0)

# Look at the result.
image.show()

Blue polygons on red background.

The approach in this quesiton might be useful, but I'm not sure how to adapt it since I am not interested in transparency, and I am working with palette ("P") images.

CodePudding user response:

I think the secret here is to work out how to draw either:

  • the polygons, or
  • everything that is not the polygons

in black on a white background. Once you have that as a "mask", you can use it as the parameter to paste() to control where any new colour or image is pasted onto your existing one.

  • Related