2010-08-27 21 views
6

Tengo dos imágenes:texturizado activa con pygame (posible qué conceptos a mirar en??)

Mask Texture

me gustaría esencialmente 'cortar' la forma negro de la textura de manera que termino con algo en este sentido:

Cutout

Excepto transparente alrededor de la forma. ¿Es esto posible usar pygame? Este ejemplo lo tuve que crear en GIMP.

Además, ¿sería demasiado pesado para el rendimiento hacer esto para cada marco para unos pocos sprites en un entorno en tiempo real? (30+ fotogramas por segundo)

Respuesta

5

Hice una solución, sin embargo, tampoco es la mejor para la velocidad ni para la belleza. Puede usar doble blitting con configuración de colorkeys para transparencia. De esta forma, la máscara debe tener solo dos colores: blanco y negro. Tenga en cuenta que no puede usar esto para imágenes con alfa por píxel (RGBA) solo para imágenes RGB. Otra restricción es que se recomienda que el tamaño de la textura y la imagen de la máscara sea el mismo (si no, debe usar áreas para blitting).

En palabras, paso a paso:

  • crear una superficie con la máscara. de fondo debe ser de color blanco (255 255 255), las partes deben ser enmascarados negro (0,0,0)
  • crear o cargar la textura en una superficie
  • establecer una clave de color de transparencia para la máscara para el color negro
  • blit la máscara sobre la textura (o sobre una copia de la textura). en este punto las partes negras de la máscara no se han redondeado a la textura porque establecemos el color negro en transparente con el método set_colorkey
  • ahora establece la clave de color de la textura (o la copia de la textura) en blanco. recuerde que nuestra superficie de textura actual tiene partes blancas y texturizadas.
  • blit la textura a la pantalla. las partes blancas no serán intercambiada debido a que nos hemos fijado a transparente con la clave de color

Ejemplo de código:

#!/usr/bin/python 
# -*- coding:utf8 -*- 

import pygame, sys 

#init pygame 
pygame.init() 

#init screen 
screen=pygame.display.set_mode((800,600)) 
screen.fill((255,0,255)) 

#loading the images 
texture=pygame.image.load("texture.jpg").convert() 
texture_rect=texture.get_rect() 
texture_rect.center=(200,300) 
mask=pygame.Surface((texture_rect.width,texture_rect.height)) # mask should have only 2 colors: black and white 
mask.fill((255,255,255)) 
pygame.draw.circle(mask,(0,0,0),(texture_rect.width/2,texture_rect.height/2),int(texture_rect.width*0.3)) 
mask_rect=mask.get_rect() 
mask_rect.center=(600,300) 

tmp_image=texture.copy() # make a copy of the texture to keep it unchanged for future usage 
mask.set_colorkey((0,0,0)) # we want the black colored parts of the mask to be transparent 
tmp_image.blit(mask,(0,0)) # blit the mask to the texture. the black parts are transparent so we see the pixels of the texture there 

tmp_rect=tmp_image.get_rect() 
tmp_rect.center=(400,300) 
tmp_image.set_colorkey((255,255,255)) 
screen.blit(texture,texture_rect) 
screen.blit(mask,mask_rect) 
screen.blit(tmp_image,tmp_rect) 

pygame.display.flip() 

while 1: 
    event=pygame.event.wait() 
    if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key in [pygame.K_ESCAPE, pygame.K_q]): 
     sys.exit() 

recomiendo no utilizar jpg como máscara debido a su formato con pérdida, lo recomiende bmp o png (bmp es mejor). Recuerde que no utiliza alfa para que los bordes no serán suavizadas por lo que no es una buena solución en 2010 :)

Aquí está la captura de pantalla del resultado: masked blitting

Editar: Hola de nuevo,

Hice algunas pruebas con blitting con BLEND_ADD y los resultados fueron prometedores.Aquí está el código:

import pygame, sys 

#init pygame 
pygame.init() 

#init screen 
screen=pygame.display.set_mode((800,600)) 
screen.fill((255,0,255)) 

#loading the images 
texture=pygame.image.load("texture.jpg").convert_alpha() 
texture_rect=texture.get_rect() 
texture_rect.center=(200,300) 
mask=pygame.image.load("mask2.png").convert_alpha() 
mask_rect=mask.get_rect() 
mask_rect.center=(600,300) 

textured_mask=mask.copy() 
textured_rect=textured_mask.get_rect() 
textured_rect.center=400,300 

textured_mask.blit(texture,(0,0),None,pygame.BLEND_ADD) 

screen.blit(texture,texture_rect) 
screen.blit(mask,mask_rect) 
screen.blit(textured_mask,textured_rect) 

pygame.display.flip() 

while 1: 
    event=pygame.event.wait() 
    if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key in [pygame.K_ESCAPE, pygame.K_q]): 
     sys.exit() 

Y el resultado: result

Con esta solución se puede obtener por texturización de píxeles alfa. Tenga en cuenta que la máscara debe ser una imagen con canal alfa, por lo que no se puede usar jpg. Lo mejor para usar es png.

imagen Textura

(texture.jpg): texture

imagen Máscara (mask2.png): mask

5

Si está utilizando imágenes con un alfa de pre-renderizados y aditivo de mezcla, se puede obtener máscaras alfa-mezclado:

import pygame 
import sys 

screen = pygame.display.set_mode((800, 600)) 
pygame.init() 

background = pygame.image.load("background.png") 
mask = pygame.image.load("mask.png") 

# Create a surface to hold the masked image 
masked_image = pygame.surface.Surface(background.get_size(), 0, mask) 
# Blit the texture normally 
masked_image.blit(background, (0,0)) 
# Multiply by the pre-rendered, inverted mask 
masked_image.blit(mask, (0,0), None, pygame.BLEND_MULT) 

# masked_image now holds the 'cutout' of your texture blended onto a black 
# background, so we need to blit it as such, i.e., using additive blending. 
screen.fill((0, 0, 0)) 
screen.blit(masked_image, (10, 10), None, pygame.BLEND_ADD) 

pygame.display.flip() 

while True: 
    event=pygame.event.wait() 
    if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key in [pygame.K_ESCAPE, pygame.K_q]): 
    sys.exit() 

Dónde background.png y mask.png son:

background.png + mask.png = result

+0

Hola gracias. Voy a intentar esto esta noche. – agscala