2010-11-25 348 views
13

是否可以使用可控的alpha顯示PyGame表面?我想用它自己的每像素alpha來表面,並以不同的透明度級別顯示它,而不會影響表面數據並保持透明度不變,即表面上的對象將保持其形狀,但其「內容」變得或多或少半透明。PyGame:每個像素的半透明子畫面alpha

換句話說,我想將源圖像中的每像素阿爾法與運行時計算的每表面阿爾法結合起來。

回答

4

在檢查PyGame和SDL文檔後,我得出結論,我問的是在PyGame中使用標準函數無法實現的。

SDL文檔指出,每個像素的alpha和per-surface alpha不能與前者一起總是採用優先級。實現我想要的效果的唯一方法是編寫一個代碼,在blit之前更新源表面的每個像素的alpha值。

4

是的,你可以。 documentation of the Surface class解釋瞭如何做到這一點。它歸結到只有兩種情況: 要麼你創建曲面物體的過程中設置了標誌:

s = pygame.Surface((16, 16), flags=pygame.SRCALPHA) 

或者你給Alpha通道的表面沒有一個尚未:

s = pygame.image.load('spam.png') 
s.convert_alpha() 

pygame.image模塊的文檔說應用convert_alpha對於具有透明度的PNG是必需的。

如果您希望可以使用模塊繪製和surfarray修改每個像素的Alpha值。指定顏色時,請使用四個整數的元組:(紅色,綠色,藍色,alpha)。 alpha參數的範圍從0(完全透明)到255(完全不透明)。

import pygame 
pygame.init() 
screen = pygame.display.set_mode((320, 200)) 
screen.fill((200, 100, 200)) 
s = pygame.Surface((64, 64), flags=pygame.SRCALPHA) 
for i in range(64): 
    pygame.draw.line(s, (0, 0, 0, i*4), (0, i), (64, i)) 

screen.blit(s, (50, 30)) 
pygame.display.flip() 
+0

+1例子總是受歡迎。特別是當它工作時,並顯示需要的東西:D – admalledd 2010-11-25 19:58:13

+5

那麼,這就解釋瞭如何顯示每像素阿爾法表面(例如從PNG文件)。我已經知道了。 但我尋找一種顯示代碼可控半透明表面的方法。例如使這些精靈從完全透明變爲原始的每像素透明度。 類似於Surface.set_alpha(),但不禁用已存在於曲面中的每像素透明度。將每像素透明度與整體透明度值進行混合。 – 2010-11-26 23:50:04

1

如果您的輸入圖像啓用了每像素alpha,但僅使用一個透明度位(例如,帶有透明背景或文本的.png精靈),則可以將透明背景轉換爲colorkey-alpha背景很容易,然後使用set_alpha()將整個紋理混合到任何東西。

這是我用褪色的文字效果和其他東西快速和骯髒的輔助函數:

def convert_to_colorkey_alpha(surf, colorkey=pygame.color.Color("magenta")): 
    newsurf = surface.Surface(surf.get_size()) 
    newsurf.fill(colorkey) 
    newsurf.blit(surf, (0, 0)) 
    newsurf.set_colorkey(colorkey) 
    return newsurf 

一對夫婦的其他技巧的可能解決這個問題可能是:

  • 做per-像素編輯修改阿爾法通道在blitting之前
  • 在您的源表面上將具有special_flags = BLEND_RGBA_MULT或BLEND_RGBA_SUB的白色或黑色填充的半透明表面擦掉。
5

Pygame documentation說,你不能用逐點Alpha結合表面α,但如果你使用pygame的1.8.1或更高版本,您可以通過使用special_flags參數.blit()解決這個問題。

我是這樣做的:

# Load an image with per-pixel alpha 
s = pygame.image.load('spam.png') 
s.convert_alpha() 

# Simulate s.set_alpha(alpha) 
alpha_img = pygame.Surface(s.get_rect().size, pygame.SRCALPHA) 
alpha_img.fill((255, 255, 255, alpha)) 
s.blit(alpha_img, (0, 0), special_flags=pygame.BLEND_RGBA_MULT) 

這種工作方式是創建一個第二面的大小和第一個相同,並使用RGBA multiplication的blit它的第一位。通過使第二個圖像的R,G和B分量等於255,乘法不會影響圖像的顏色,但它會按給定的alpha因子縮放alpha通道。

請注意,上述方法與撥打set_alpha()的不同之處在於set_alpha()可以通過調用set_alpha(255)來逆轉。如果使用上述方法,將導致每個像素的像素阿爾法被改變,所以該過程不能直接顛倒過來。