2012-03-30 21 views
5

Ho un'immagine png come sfondo e voglio aggiungere una mesh trasparente a questo sfondo ma questo non funziona come previsto. L'immagine di sfondo viene convertita in trasparente nei luoghi in cui applico la mesh trasparente.Unione di sfondo con immagine trasparente in PIL

che sto facendo:

from PIL import Image, ImageDraw 

map_background = Image.open(MAP_BACKGROUND_FILE).convert('RGBA') 
map_mesh = Image.new('RGBA', (width, height), (0, 0, 0, 0)) 
draw = ImageDraw.Draw(map_mesh) 

# Create mesh using: draw.line([...], fill=(255, 255, 255, 50), width=1) 
... 

map_background.paste(map_mesh, (0, 0), map_mesh) 

Ma il risultato è:

enter image description here

si può vedere un modello a scacchiera se si guarda con attenzione (utilizzato in programmi di grafica come senza sfondo). Le linee trasparenti rendono il livello di sfondo trasparente anche nei punti in cui entrambi i livelli si sono incontrati. Ma voglio solo che la linea trasparente sia aggiunta in cima allo sfondo.

posso risolverlo con:

map_background.paste ((255,255,255), (0, 0), map_mesh)

ma come io uso i colori diversi per diverse linee, avrei dovuto fare per ogni colore questo processo. Se avessi 100 colori, quindi ho bisogno di 100 strati che non è una soluzione molto buona.

+0

Eventuali duplicati di http://stackoverflow.com/questions/5324647/how-to-merge-a-transparent-png-image-with-another-image-using- pil –

risposta

10

Quello che stai cercando di fare è di comporre la griglia sullo sfondo, e per questo è necessario utilizzare Image.blend o Image.composite. Ecco un esempio utilizzando quest'ultimo di linee rosse composito con valori alfa casuali su uno sfondo bianco:

import Image, ImageDraw, random 
background = Image.new('RGB', (100, 100), (255, 255, 255)) 
foreground = Image.new('RGB', (100, 100), (255, 0, 0)) 
mask = Image.new('L', (100, 100), 0) 
draw = ImageDraw.Draw(mask) 
for i in range(5, 100, 10): 
    draw.line((i, 0, i, 100), fill=random.randrange(256)) 
    draw.line((0, i, 100, i), fill=random.randrange(256)) 
result = Image.composite(background, foreground, mask) 

Da sinistra a destra: sfondo, maschera, primo piano, risultato:

backgroundmaskforegroundcomposite

(Se sei felice di riportare il risultato all'immagine di sfondo, puoi utilizzare una delle versioni mascherate di Image.paste, come indicato da Paulo Scardine in una risposta cancellata.)

0

Ho avuto difficoltà a ottenere gli esempi sopra per funzionare bene. Invece, questo ha funzionato per me:

import numpy as np 
import Image 
import ImageDraw 

def add_craters(image, craterization=20.0, width=256, height=256): 

    foreground = Image.new('RGBA', (width, height), (0, 0, 0, 0)) 
    draw = ImageDraw.Draw(foreground) 

    for c in range(0, craterization): 
     x = np.random.randint(10, width-10) 
     y = np.random.randint(10, height-10) 
     radius = np.random.randint(2, 10) 
     dark_color = (0, 0, 0, 128) 
     draw.ellipse((x-radius, y-radius, x+radius, y+radius), fill=dark_color) 

    image_new = Image.composite(foreground, image, foreground) 
    return image_new