2010-08-27 80 views
6

我有兩個圖像:主動與紋理pygame的(可能是什麼概念到?)

Mask Texture

我想主要從紋理片「切出」黑色形狀讓我最終沿着這些路線的東西:

Cutout

除了形狀周圍的透明。這可能使用pygame嗎?我必須在GIMP中創建這個例子。

此外,在實時環境中爲幾個精靈的每個幀執行此操作的性能會太高嗎? (每秒30幀以上)

回答

5

我做了一個解決方案,但它不是最好的速度或美麗。 您可以使用雙色條設置色彩來設置透明度。這樣的面具應該只有兩種顏色:黑色和白色。 請注意,您不能將此圖像用於每像素alpha(RGBA)的圖像僅適用於RGB圖像。 其他限制是建議紋理和蒙板圖像的大小相同(如果不是,則應使用區域進行blitting)。

在話,分步:

  • 創建一個表面與掩模。背景應爲白色(255,255,255),所述掩蔽的部分應該是黑色(0,0,0)
  • 創建或紋理加載到表面
  • 設置了掩模的透明度的colorkey爲黑色
  • 的blit遮罩到紋理上(或紋理的副本上)。在這一點上,面具的黑色部分沒有傳到紋理上,因爲我們使用set_colorkey方法將黑色設置爲透明,現在將紋理的顏色鍵(或紋理的副本)設置爲白色。請記住,我們當前的紋理表面具有白色和紋理部分。
  • 將紋理投影到屏幕上。白色的部分將不會被位圖混合,由於我們把它設置爲透明的colorkey的

代碼示例:

#!/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() 

我建議不要使用,因爲它有損格式的JPG作爲面膜,我推薦bmp或png(bmp更好)。請記住它不使用字母,使邊緣不會消除鋸齒的,所以它不是在2010年一個很好的解決方案:)

下面是結果的截圖: masked blitting

編輯: 嗨再次,

我用BLEND_ADD做了一些測試,結果很有希望。下面是代碼:

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() 

而結果: result

有了這個解決方案可以在每個像素的阿爾法紋理得到。請注意,面具應該是一個帶alpha通道的圖像,所以jpg無法使用。最好用的是png。

的紋理圖像(texture.jpg): texture

面膜圖像(mask2.png): mask

5

如果您使用與預渲染α和添加劑混合,可以圖像得到阿爾法混合口罩:

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() 

background.pngmask.png是:

background.png + mask.png = result

+0

嘿謝謝。今晚我會試試這個。 – agscala 2010-09-07 14:47:27