2016-02-11 16 views
6

nel mio gioco pygame, per importare immagini JPEG, io uso convert() http://www.pygame.org/docs/ref/surface.html#pygame.Surface.convertPygame, impostare la trasparenza su un'immagine importati utilizzando convert_alpha()

poi, a giocare con la trasparenza dell'immagine (quanto possiamo vedere attraverso gli immagine), io uso set_alpha() http://www.pygame.org/docs/ref/surface.html#pygame.Surface.set_alpha

Tuttavia, per importare la mia immagine png, che hanno uno sfondo tranparent, io uso convert_alpha() http://www.pygame.org/docs/ref/surface.html#pygame.Surface.convert_alpha

ma con questo modo di importare, non posso giocare con la trasparenza generale usando set_alpha(). Qualche altra idea per regolare la trasparenza (quanto vediamo attraverso l'immagine)?

risposta

6

Quando si legge la documentazione per set_alpha si può leggere questo: Se il formato di superficie contiene per alfa dei pixel, allora questo valore alfa viene ignorato.

% Nel tuo caso, con un'immagine png, è un alfa per pixel. Quindi, devi gestire alpha "per pixel". Ad esempio, si può fare (non il codice migliore, ma facile da capire lavoro con png con no si solo trasparenza /.):

def change_alpha(img,alpha=255): 
    width,height=img.get_size() 
    for x in range(0,width): 
    for y in range(0,height): 
     r,g,b,old_alpha=img.get_at((x,y)) 
     if old_alpha>0: 
     img.set_at((x,y),(r,g,b,alpha)) 

Attenzione, è "lento", a causa di gestire ogni pixel che non è a 0 (trasparente dal tuo png). Se il png ha più livelli di trasparenza, è necessario gestire la trasparenza con una formula migliore, in questo modo:

 r,g,b,old_alpha=img.get_at((x,y)) 
     img.set_at((x,y),(r,g,b,(alpha*old_alpha)/255)) 

E in questo caso, non modificare l'immagine originale, ma il lavoro su una copia per non perdere mai il vostro alfa originale.

spero che vi aiuterà

===================== EDIT =============== ==== Aggiungete un po 'di ottimizzazione, perché chiedere a commento

Con una certa metodologia di caching:

class image_with_alpha(object): 
    def __init__(self,name=None): 
     self.img=None 
     self.alpha={} 
     if name: 
      self.load_image(name) 

    def load_image(self,name): 
     self.img=pygame.image.load(name) 
     self.alpha[255]=self.img 
     #self.pre_compute_alpha() 

    def pre_compute_alpha(self): 
     for alpha in range(0,10): 
      self.alpha[alpha]=change_alpha(self.img,alpha) 

    def get_img(self,a=255): 
     try: 
      return self.alpha[a] 
     except: 
      self.alpha[a]=change_alpha(self.img,a) 
     return self.alpha[a] 

e usarlo in questo modo: immagine carico:

image=image_with_alpha("test.png") 

Blit con 60 per alpha:

screen.blit(image.get_img(60),(0,0)) 

E ora, è veloce spero

+0

Ho una cornice nera con la prima formula, ma la seconda funziona bene :), tuttavia è molto lenta, il mio gioco scende a 25 fps ... – n0tis

+0

qualsiasi idea di fare è più ottimizzato? – n0tis

+0

Non so come funzioni il tuo gioco, e l'ottimizzazione di un tale codice dipende da come viene utilizzata. quanto tempo cambia l'alfa? Quanto sono grandi le immagini? Senza la programmazione di basso livello, puoi usare "cache" per i dati: userai più memoria, ma precalcerai alpha per l'immagine mostrerà grandi miglioramenti senza molti lavori. –

0

utilizzare set_colorkey (colore) per impostare un colore trasparente. per esempio, se hai un'immagine di una mela, e tutto tranne la mela è di colore nero, dovresti usare apple.set_colorkey (nero), e tutto tranne la mela sarebbe trasparente. inoltre, se hai problemi con l'uso di un'immagine jpg, ti suggerisco di cambiarlo in png e poi fare .convert().

+0

non hai capito la mia domanda. Sto già usando il file png. 'convert()' sta facendo black frame sul mio png, quindi uso 'convert_alpha' invece. Il problema chiave è che voglio configurare anche la trasparenza generale (quanto vediamo attraverso l'intera immagine). Normalmente, io uso 'set_alpha()' per questo obiettivo. Tuttavia, quando importi un'immagine usando 'convert_alpha()' come faccio io, 'set_alpha()' non funziona. Sto cercando un'alternativa 'set_alpha()' – n0tis

1

Ok ho la risposta per voi. La funzione "convert_alpha()" di Pygame non supporta pixel alpha. In base all'impostazione dei documenti, alpha non avrà alcun effetto. Tuttavia, puoi aggirare questa limitazione facendo quanto segue. Se carichi la tua immagine usando "convert()", e quindi settando alpha puoi rendere l'immagine trasparente.Quindi tutto ciò che devi fare è usare "set_colorkey (colore di sfondo)" per eliminare l'immagine di sfondo. Siate cauti con colorkey perché qualsiasi colore nell'immagine impostata come colorkey diventerà trasparente. La colorkey non interessa per pixel alpha, quindi puoi cambiare l'alfa di un'immagine e usare colorkey allo stesso tempo.

Ecco il codice ...

#Loading Image 
image = pygame.image.load("test.png").convert() 

#Setting Alpha 
image.set_alpha(some desired alpha) 

#Set colorkey To Eliminate Background Color 
image.set_colorkey(some background color) 

ho buttato questa immagine di prova insieme per testare il codice. L'immagine ha una trasparenza attorno ai bordi di essa.

This is what it looks like blitted onto a green background without the added alpha. The white part was transparent until loaded with ".convert()"

This is the finished look of the image with the whole code applied. The alpha has been stripped and reset, and the colorkey has been set to white because it was the background

Spero che questo è quello che stai cercando e sperato la mia risposta ha aiutato qui.

NOTA * È possibile effettuare una copia dell'immagine prima di modificarne l'alfa in questo modo senza il rischio che l'immagine abbia un effetto "spillover" dagli usi precedenti.

2

La soluzione più veloce è probabilmente quella di utilizzare la manipolazione dell'array numpy, dovrebbe essere abbastanza veloce da evitare la necessità di memorizzare la cache. Nei molto lento sul calcolo del valore alfa pixel-saggio è iterazione in Python, mentre numpy fa tutto in C.

Iniziare facendo riferimento canale alfa dell'immagine in una matrice numpy. Questo creerà un blocco sulla superficie dell'immagine; ricordiamolo per dopo. Quindi prendi il minimo (pixel-saggio) dell'alfa originale e un array pieno di uno (che ti lascerà con una serie di soli uno e zero), moltiplicalo (in pixel) per l'alfa desiderato e copia il risultato indietro al canale alfa dell'immagine (rappresentato ancora da quel riferimento di matrice). Prima di poter blittare l'immagine sullo schermo, il riferimento dell'array all'array alfa deve essere cancellato, rilasciando il blocco sulla superficie dell'immagine.

def change_alpha(img, alpha=255): 
    chan = pygame.surfarray.pixels_alpha(img) 
    chan2 = numpy.minimum(chan, numpy.ones(chan.shape, dtype=chan.dtype)) * alpha 
    numpy.copyto(chan, chan2) 
    del chan 
Problemi correlati