-
@jeremydouglass, if I remember correctly, came up with this strategy to get the most transparent bits (pun intended) between an image and a mask, originally in Java. And I ported it to Python, using a list comprehension: def setup():
global offscreen, clip_mask
size(500, 500)
offscreen = create_graphics(width, height)
offscreen.begin_draw()
offscreen.clear() # fundo transparente
# offscreen.background(0, 200, 0, 100) # é possível fundo translúcido
offscreen.fill(255, 0, 0, 128) # vermelho translúcido
for _ in range(100):
offscreen.rect(random(width), random(height), 50, 50)
offscreen.end_draw()
def draw():
background(150, 150, 200)
y = frame_count % height
line(0, y, width, y)
clip_mask = create_graphics(width, height)
clip_mask.begin_draw()
clip_mask.fill(255)
clip_mask.circle(mouse_x, mouse_y, 250)
clip_mask.end_draw()
result = offscreen.copy()
# sem o mouse apertado é mais rápido (desconsidera alpha da imagem
# original)
if is_mouse_pressed:
result.mask(min_alphas(offscreen, clip_mask))
else:
result.mask(clip_mask) # máscara normal
image(result, 0, 0) # desenha na tela a imagem com a máscara aplicada
def min_alphas(img1, img2):
"""Devolve pixels com alfa do mais transparente de cada par de pixels"""
img1.load_pixels()
img2.load_pixels()
return [min(pix1 >> 24 & 0xFF, pix2 >> 24 & 0xFF) # dark magic, don't ask
for pix1, pix2 in zip(img1.pixels, img2.pixels)] Could we get rid of the list comprehension with some vectorized strategy? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
I like this question. There is a good solution using py5's numpy tools. Using a Py5Graphics object to create the mask is a good idea: clip_mask = create_graphics(width, height)
clip_mask.begin_draw()
clip_mask.fill(255)
clip_mask.circle(mouse_x, mouse_y, 250)
clip_mask.end_draw() Then you can do something like this: clip_mask.load_np_pixels()
offscreen.load_np_pixels()
# copy clip_mask's red channel to offscreen's alpha channel
offscreen.np_pixels[:, :, 0] = clip_mask.np_pixels[:, :, 1]
offscreen.update_np_pixels()
image(offscreen, 0, 0) You should also put all the The working code is as follows: def setup():
global offscreen, clip_mask
size(500, 500)
clip_mask = create_graphics(width, height)
offscreen = create_graphics(width, height)
offscreen.begin_draw()
offscreen.clear() # fundo transparente
# offscreen.background(0, 200, 0, 100) # é possível fundo translúcido
offscreen.fill(255, 0, 0, 128) # vermelho translúcido
for _ in range(100):
offscreen.rect(random(width), random(height), 50, 50)
offscreen.end_draw()
def draw():
background(150, 150, 200)
y = frame_count % height
line(0, y, width, y)
clip_mask.begin_draw()
clip_mask.background(0)
clip_mask.fill(255)
clip_mask.circle(mouse_x, mouse_y, 250)
clip_mask.end_draw()
clip_mask.load_np_pixels()
offscreen.load_np_pixels()
# copy clip_mask's red channel to offscreen's alpha channel
offscreen.np_pixels[:, :, 0] = clip_mask.np_pixels[:, :, 1]
offscreen.update_np_pixels()
image(offscreen, 0, 0) |
Beta Was this translation helpful? Give feedback.
I like this question. There is a good solution using py5's numpy tools.
Using a Py5Graphics object to create the mask is a good idea:
Then you can do something like this:
You should also put all the
create_graphics()
calls insetup()
. It is a slow operation to create a new one fo…