首页 > 解决方案 > Pillow / Numpy 中的高效粘贴/复合蒙版图像

问题描述

我有两个png图像:

heart40.png (40x40 透明背景) -- https://imgur.com/27qbUw2

background40.png (40x40) -- https://imgur.com/pxF5u62

图像被分割成 8x8 像素的网格,从 1 开始编号——

---------------------
| 1 | 2 | 3 | 4 | 5 |
---------------------
| 6 |    ...    |10 |

...

|21 |    ...    |25 |
---------------------

我只想要从 heart40.png 中选择的网格,例如 (1, 5, 8, 13, 23) 覆盖到 background40.png,结果 - https://imgur.com/NLq5pKH

我正在使用 Pillow(除非有显示停止器,否则真的不想切换到另一个图像库)。以下代码有效 -

import numpy as np
from math import ceil
from PIL import Image, ImageDraw


def square_id_to_xy(square_id):
    grid_count = int(40 / 8)
    y_id = ceil(square_id / grid_count)
    x_id = square_id - (grid_count * (y_id-1))
    return (x_id-1) * 8, (y_id-1) * 8


if __name__ == '__main__':
    im = Image.open("heart40.png").convert("RGBA")
    background_im = Image.open("background40.png").convert("RGBA")
    mask_im = Image.alpha_composite(background_im, im)
    show_square_ids = (1, 5, 8, 13, 23)
    for square_id in range(1, 26):
        if square_id in show_square_ids:
            continue
        x, y = square_id_to_xy(square_id)
        ImageDraw.Draw(mask_im).rectangle([(x, y), (x+7, y+7)], outline=0, fill=1)
    background_im.paste(mask_im, (0, 0), mask_im)
    background_im.save("background_pasted.png")

当我为所有不想显示的网格绘制透明方块,当有数千个网格但我只想显示其中的几个时,这可能会相当低效。

所以问题是:有没有更有效的方法?

标签: pythonnumpypython-imaging-library

解决方案


我很着急,但有一个你可以使用的想法,即使我不编写和测试所有代码......

grid=np.arange(1,26).reshape(5,5)

会给你这个:

array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10],
       [11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20],
       [21, 22, 23, 24, 25]])

然后确定你想要什么:

wanted=[1,5,8,13,23]

并用于numpy.isin()测试是否需要每个网格:

mask=np.isin(grid,wanted)

这给了你:

array([[ True, False, False, False,  True],
       [False, False,  True, False, False],
       [False, False,  True, False, False],
       [False, False, False, False, False],
       [False, False,  True, False, False]])

您现在可以将其乘以 255,这将为您提供黑白蒙版。您可以将蒙版制作成图像并使用 NEAREST_NEIGHBOUR 重新采样将其放大 5 倍以使其尺寸正确。


推荐阅读