高效粘贴/枕头中的复合蒙版图像/块状

时间:2018-10-05 06:02:34

标签: python numpy python-imaging-library

我有两个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")

当我为不想显示的所有网格绘制透明正方形时,当有成千上万个网格时,这可能效率很低,但我只想显示其中的几个。

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

1 个答案:

答案 0 :(得分:1)

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

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倍,以使其正确大小。