2012-03-30 41 views
5

Tengo una imagen png como fondo y quiero agregar una malla transparente a este fondo pero esto no funciona como se esperaba. La imagen de fondo se convierte en transparente en los lugares donde aplico malla transparente.Fusión de fondo con imagen transparente en PIL

que estoy haciendo:

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) 

pero el resultado es:

enter image description here

se puede ver un patrón de tablero de ajedrez si se fijan bien (utilizado en los programas de gráficos como sin fondo). Las líneas transparentes hacen que la capa de fondo sea transparente también en los lugares donde ambas capas se encontraron. Pero solo quiero que se agregue la línea transparente sobre el fondo.

puedo solucionarlo con:

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

pero como usar diferentes colores para las diferentes líneas, que tendría que hacer para cada color este proceso. Si tuviera 100 colores, entonces necesito 100 capas, lo que no es una buena solución.

+0

Posible duplicado de http://stackoverflow.com/questions/5324647/how-to-merge-a-transparent-png-image-with-another-image-using- pil –

Respuesta

10

Lo que estás tratando de hacer es componer la grilla en el fondo, y para eso necesitas usar Image.blend o Image.composite. Aquí hay un ejemplo usando el último a líneas rojas compuestos con valores alfa al azar sobre un fondo blanco:

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) 

De izquierda a derecha: fondo, máscara, primer plano, resultado:

backgroundmaskforegroundcomposite

(Si está satisfecho con escribir el resultado en la imagen de fondo, puede usar una de las versiones enmascaradas de Image.paste, como se indica en Paulo Scardine en una respuesta eliminada)

0

Tuve problemas para que los ejemplos anteriores funcionaran correctamente. En su lugar, esto funcionó para mí:

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 
Cuestiones relacionadas