[英]How to make a cut-out/make the background of an image transparent using opencv?
[英]How to blit a tranparent image in pygame to make an alpha “cut-out”
給定一個充滿一些像素的pygame曲面,我想以編程方式在該圖像中創建一個Alpha通道“窗口”(這樣背景就會顯示出來)。
顯然,我意識到可以使用位圖編輯器輕松完成此操作,問題的關鍵是作為不同,更復雜的操作的一部分即時進行此操作。
因此,我制作了一個在“全紅”和“帶孔的紅色”圖像之間切換的精靈,並嘗試通過將完全透明的圖像塗抹到基本位圖上來動態創建位圖窗口。
我認為正在發生的是,PyGame沒有繪制完全透明的像素,因為它們是透明的! 有什么方法可以使它們變薄,從而制成窗戶嗎?
我嘗試添加pygame.BLEND_RGBA_MIN
和其他 (根據“ 需要在Pygame中 pygame.BLEND_RGBA_MIN
表面透明性的建議”),但未能獲得所需的結果。
我得到的只是一個以紅色為中心的黑色正方形,而不是背景的窗口。
import pygame
# Window size
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 400
FPS = 60
# background colours
INKY_BLACK = (128, 128, 128)
class HoleSprite( pygame.sprite.Sprite ):
def __init__( self ):
pygame.sprite.Sprite.__init__( self )
# Make a full-image (no hole)
self.base_image = pygame.Surface( ( 32, 32 ), pygame.SRCALPHA )
self.base_image.fill( ( 255,0,0 ) )
# Make an image with a see-through window
self.hole_image = pygame.Surface( ( 32, 32 ), pygame.SRCALPHA )
self.hole_image.fill( ( 255,0,0 ) )
self.hole = pygame.Surface( ( 10, 10 ), pygame.SRCALPHA )
self.hole.fill( ( 0, 0, 0, 255 ) ) # transparent
self.hole_image.blit( self.hole, [ 10,10, 10,10 ] ) # punch the middle out?
# sprite housekeeping
self.image = self.base_image
self.rect = self.image.get_rect()
self.rect.x = WINDOW_WIDTH // 2 # centred
self.rect.y = WINDOW_HEIGHT // 2
self.last = 0
def update( self ):
time_ms = pygame.time.get_ticks()
# FLip the images each second
if ( time_ms - self.last > 1000 ):
if ( self.image == self.hole_image ):
self.image = self.base_image
else:
self.image = self.hole_image
self.last = time_ms
### MAIN
pygame.init()
pygame.font.init()
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
WINDOW = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), SURFACE )
pygame.display.set_caption("Hole Srite Test")
anims = pygame.sprite.GroupSingle()
holey = HoleSprite( )
anims.add( holey )
clock = pygame.time.Clock()
done = False
while not done:
# Handle user-input
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
# Repaint the screen
anims.update()
WINDOW.fill( INKY_BLACK )
anims.draw( WINDOW )
pygame.display.flip()
# Update the window, but not more than 60fps
clock.tick_busy_loop( FPS )
pygame.quit()
首先:您需要(0,0,0,0)
而不是(0,0,0,255)
第二:您必須使用fill(color, rect)
直接在紅色矩形中創建透明孔。
self.hole_image.fill( (0, 0, 0, 0), (10, 10, 10, 10) )
或者您可以直接在紅色表面上繪制透明矩形
pygame.draw.rect(self.hole_image, (0, 0, 0, 0), (10, 10, 10, 10) )
當您在全彩色圖像上對透明圖像進行blit時,它不會替換像素,但會同時混合兩種顏色(透明和全色),您會獲得全彩色。
blit()
具有標志BLEND_ADD
, BLEND_SUB
, BLEND_MULT
等,也許使用此標志之一可以替換像素,但我從未嘗試過。
其他信息: pygame透明度
完整代碼:
import pygame
# Window size
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 400
FPS = 60
# background colours
INKY_BLACK = (128, 128, 128)
class HoleSprite( pygame.sprite.Sprite ):
def __init__( self ):
pygame.sprite.Sprite.__init__( self )
# Make a full-image (no hole)
self.base_image = pygame.Surface( ( 32, 32 ), pygame.SRCALPHA )
self.base_image.fill( ( 255,0,0 ) )
# Make an image with a see-through window
self.hole_image = pygame.Surface( ( 32, 32 ), pygame.SRCALPHA )
self.hole_image.fill( ( 255,0,0 ) )
self.hole_image.fill( (0, 0, 0, 0), (10, 10, 10, 10) )
# OR
#pygame.draw.rect(self.hole_image, (0, 0, 0, 0), (10, 10, 10, 10) )
# sprite housekeeping
self.image = self.base_image
self.rect = self.image.get_rect()
self.rect.x = WINDOW_WIDTH // 2 # centred
self.rect.y = WINDOW_HEIGHT // 2
self.last = 0
def update( self ):
time_ms = pygame.time.get_ticks()
# FLip the images each second
if ( time_ms - self.last > 1000 ):
if ( self.image == self.hole_image ):
self.image = self.base_image
else:
self.image = self.hole_image
self.last = time_ms
### MAIN
pygame.init()
pygame.font.init()
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
WINDOW = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), SURFACE )
pygame.display.set_caption("Hole Srite Test")
anims = pygame.sprite.GroupSingle()
holey = HoleSprite( )
anims.add( holey )
clock = pygame.time.Clock()
done = False
while not done:
# Handle user-input
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
# Repaint the screen
anims.update()
WINDOW.fill( INKY_BLACK )
anims.draw( WINDOW )
pygame.display.flip()
# Update the window, but not more than 60fps
clock.tick_busy_loop( FPS )
pygame.quit()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.