You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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模式,无需转换色彩模式、无需处理透明通道:

  1. 保留原有热力图绘制逻辑不变,得到绘制完成的P模式热力图
  2. 新建和热力图尺寸、调色板完全一致的底图,全图填充为外部区域需要的目标颜色(示例中为蓝色,对应调色板索引0)
  3. 新建同尺寸的灰度("L"模式)遮罩层,初始全黑(像素值0,代表粘贴时不保留原热力图内容),将所有目标多边形内部填充为白色(像素值255,代表粘贴时保留原热力图内容)
  4. 将原热力图通过遮罩粘贴到纯色底图上,最终得到的底图即为目标结果

修改后的可运行代码:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 12:03:16