Zrobiłem rozwiązanie, jednak nie jest ono najlepsze ani dla prędkości, ani dla piękna. Możesz użyć podwójnego blittingu z ustawieniem koloru dla przezroczystości. W ten sposób maska powinna mieć tylko dwa kolory: czarny i biały. Należy pamiętać, że nie można tego użyć w przypadku obrazów z pikselami alfa (RGBA) tylko dla obrazów RGB. Inne ograniczenie polega na tym, że zaleca się, aby rozmiar tekstury i obraz maski był taki sam (jeśli nie, należy użyć obszarów do blendingu).
słowami, krok po kroku:
- utworzyć powierzchnię maski. Tło powinno być biały (255,255,255), maskowane części powinny być czarna (0,0,0)
- utworzyć lub załadować teksturę na powierzchni
- ustawiony na kolor kluczowy przezroczystości dla maski dla koloru czarnego
- Blit maskę na teksturę (lub na kopię tekstury). w tym momencie czarne części maski nie zostały pobrudzone do tekstury, ponieważ ustawiliśmy czarny kolor na przezroczysty za pomocą metody set_colorkey, aby ustawić kolor biały tekstury (lub kopii tekstury) na biały. pamiętaj, że nasza obecna powierzchnia tekstur ma białe i teksturowane części.
- blit tekstury na ekranie. białe części nie będą blittowany powodu musimy ustawić go przezroczysta z kolor klucza
przykładowy kod:
#!/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()
Polecam nie używać jpg jak maska z powodu jego stratny format, ja polecam bmp lub png (bmp jest lepszy). Pamiętaj, że nie wykorzystuje alfa więc krawędzie nie będą wygładzane tak, że nie jest to miłe rozwiązanie w 2010 roku :)
Oto zrzut ekranu z wynikiem:
Edit: Witam ponownie,
Zrobiłem kilka testów z blendingiem z BLEND_ADD, a wyniki były obiecujące.Oto kod:
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()
A wynik:
Dzięki takiemu rozwiązaniu można uzyskać na piksel alfa teksturowania. Należy pamiętać, że maska powinna być obrazem z kanałem alfa, więc nie można użyć jpg. Najlepszym rozwiązaniem jest png.
obrazu tekstury (texture.jpg):
Maska obrazu (mask2.png):
Hej dzięki. Zamierzam spróbować tego dziś wieczorem. – agscala