如何在Pillow调色板(P)模式图像中填充多边形外所有区域
Pillow P模式图像保留多边形内部内容、填充外部区域实现方法
需求场景
使用Python Pillow库制作热力图时,需要在热力图绘制完成后清空指定多边形区域外的所有内容:
- 现有逻辑可实现多边形内部填充、保留外部背景,和需求正好相反
- 需求为:将多边形外部区域统一填充为指定颜色(示例中为蓝色),完全保留多边形内部的原有热力图内容
- 处理的图像为调色板(
"P")模式,不需要透明效果,无法直接套用多边形外透明化的参考方案
示例原有代码(效果为红底蓝色多边形,和需求相反):
from PIL import Image, ImageDraw # 全红图像代表实际计算生成的热力图,非纯色 image = Image.new("P", (500, 500), 1) image.putpalette([ 0, 0, 255, 255, 0, 0 ]) draw = ImageDraw.Draw(image) # 实际场景中多边形结构更复杂,单个多边形包含数千个点位 polygons = [[(100, 100), (100, 400), (350, 50)], [(150, 450), (400, 300), (450, 50)]] # 现有逻辑:填充多边形内部为蓝色,保留外部红色背景,和需求相反 for polygon in polygons: draw.polygon(polygon, fill=0, outline=None, width=0) image.show()

实现方案
通过遮罩层+图像粘贴的方式实现,全程适配P模式,无需转换色彩模式、无需处理透明通道:
- 保留原有热力图绘制逻辑不变,得到绘制完成的P模式热力图
- 新建和热力图尺寸、调色板完全一致的底图,全图填充为外部区域需要的目标颜色(示例中为蓝色,对应调色板索引0)
- 新建同尺寸的灰度(
"L"模式)遮罩层,初始全黑(像素值0,代表粘贴时不保留原热力图内容),将所有目标多边形内部填充为白色(像素值255,代表粘贴时保留原热力图内容) - 将原热力图通过遮罩粘贴到纯色底图上,最终得到的底图即为目标结果
修改后的可运行代码:
from PIL import Image, ImageDraw # 原有热力图绘制逻辑,无需修改 image = Image.new("P", (500, 500), 1) image.putpalette([ 0, 0, 255, # 索引0:蓝色,外部区域填充色 255, 0, 0 # 索引1:红色,代表热力图内容 ]) # 实际使用时替换为你自己的热力图绘制逻辑 # draw_heatmap(image) polygons = [[(100, 100), (100, 400), (350, 50)], [(150, 450), (400, 300), (450, 50)]] # 外部区域填充逻辑 # 1. 生成全为目标填充色的底图,复用原图调色板 bg = Image.new("P", image.size, 0) bg.putpalette(image.getpalette()) # 2. 生成区域遮罩 mask = Image.new("L", image.size, 0) mask_draw = ImageDraw.Draw(mask) for polygon in polygons: mask_draw.polygon(polygon, fill=255) # 3. 按遮罩将原热力图粘贴到底图上 bg.paste(image, (0, 0), mask=mask) # 查看结果:蓝底红色多边形,仅保留多边形内部的热力图内容 bg.show()
方案优势
- 原生支持P模式图像,不会破坏原有调色板配置,无需转换为RGB/RGBA模式
- 无透明通道,最终输出为完全不透明的图像,符合需求
- 多边形绘制由Pillow底层实现,就算单个多边形包含数千点位也能保持较好的处理性能
内容的提问来源于stack exchange,提问作者Anders
相关产品推荐
相关产品推荐

