2

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.

Anders
  • 8,307
  • 9
  • 56
  • 88
  • I don't really understand what the difficulty is. You need to find a way to either draw the polygons, or the *"not the polygons"*. Can you draw the polygons in solid black on a solid white background? If so, you can create a mask and use it with `paste()` to paste a new colour onto your real image. – Mark Setchell Jun 28 '22 at 08:19
  • Or, if you start at top-left corner (0,0) you should be able to flood-fill, stopping at the blue. https://pillow.readthedocs.io/en/stable/reference/ImageDraw.html?highlight=Floodfill#PIL.ImageDraw.floodfill – Mark Setchell Jun 28 '22 at 08:21
  • @MarkSetchell The difficulty is not knowing that you can use a mask with the paste method, but now I do. Thanks. Feel free to post the comment as an answer. – Anders Jun 28 '22 at 11:22
  • Glad the comment helped turn on a light somewhere. Good luck with your project. – Mark Setchell Jun 28 '22 at 12:08

1 Answers1

2

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.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432