8

tengo un logotipo cuadrado y necesito round_corner que, buscado por un tiempo y ya dispone del código de seguimiento "de trabajo":cómo redondear la esquina de un logotipo sin fondo blanco (¿transparente?) Con pil?

def round_corner_jpg(image, radius): 
    """generate round corner for image""" 
    mask = Image.new('RGB', image.size) 
    #mask = Image.new('RGB', (image.size[0] - radius, image.size[1] - radius)) 
    #mask = Image.new('L', image.size, 255) 
    draw = aggdraw.Draw(mask) 
    brush = aggdraw.Brush('black') 
    width, height = mask.size 
    draw.rectangle((0,0,width,height), aggdraw.Brush('white')) 
    #upper-left corner 
    draw.pieslice((0,0,radius*2, radius*2), 90, 180, None, brush) 
    #upper-right corner 
    draw.pieslice((width - radius*2, 0, width, radius*2), 0, 90, None, brush) 
    #bottom-left corner 
    draw.pieslice((0, height - radius * 2, radius*2, height),180, 270, None, brush) 
    #bottom-right corner 
    draw.pieslice((width - radius * 2, height - radius * 2, width, height), 270, 360, None, brush) 
    #center rectangle 
    draw.rectangle((radius, radius, width - radius, height - radius), brush) 
    #four edge rectangle 
    draw.rectangle((radius, 0, width - radius, radius), brush) 
    draw.rectangle((0, radius, radius, height-radius), brush) 
    draw.rectangle((radius, height-radius, width-radius, height), brush) 
    draw.rectangle((width-radius, radius, width, height-radius), brush) 
    draw.flush() 
    del draw 
    return ImageChops.add(mask, image) 

entonces me salvó el objeto de imagen devuelto, sin embargo, tiene el fondo blanco en la esquina like this ¿Cómo puedo eliminar el fondo blanco o hacerlo invisible? Gracias de antemano ~

EDIT: aquí está el código de Fraxel, gracias ~

def add_corners(im, rad): 
    circle = Image.new('L', (rad * 2, rad * 2), 0) 
    draw = ImageDraw.Draw(circle) 
    draw.ellipse((0, 0, rad * 2, rad * 2), fill=255) 
    alpha = Image.new('L', im.size, "white") 
    w, h = im.size 
    alpha.paste(circle.crop((0, 0, rad, rad)), (0, 0)) 
    alpha.paste(circle.crop((0, rad, rad, rad * 2)), (0, h - rad)) 
    alpha.paste(circle.crop((rad, 0, rad * 2, rad)), (w - rad, 0)) 
    alpha.paste(circle.crop((rad, rad, rad * 2, rad * 2)), (w - rad, h - rad)) 
    im.putalpha(alpha) 
    return im 


if __name__ == '__main__': 
    im = Image.open('1.jpg') 
    im = add_corners(im, 100) 
    im.save('out.png')` 

estoy tan sorry..I necesitan la forma de la imagen a ser elipse no rectángulo, es decir. las cosas de escritura fuera de la foto, y @fraxel, todavía puedo ver la esquina blanca en la foto que procesaste para mí

Respuesta

14

En primer lugar, asegúrese de que está guardando su imagen en un formato que es compatible con la transparencia. PNG does, JPG does not ... A continuación se muestra un bonito código que agregará esquinas transparentes. Funciona así:

  1. dibuja un círculo con un radio, rad, utilizando draw.ellipse()
  2. crear una imagen para el canal alfa del mismo tamaño que su imagen
  3. Picar nuestro círculo en cuatro partes (las esquinas redondeadas), y colocarlos en las esquinas correctas de la imagen alfa
  4. Ponga el canal alfa en la imagen con putalpha()
  5. Guardar como png, preservando así la transparencia.

Aquí está el código:

import Image, ImageDraw 

def add_corners(im, rad): 
    circle = Image.new('L', (rad * 2, rad * 2), 0) 
    draw = ImageDraw.Draw(circle) 
    draw.ellipse((0, 0, rad * 2, rad * 2), fill=255) 
    alpha = Image.new('L', im.size, 255) 
    w, h = im.size 
    alpha.paste(circle.crop((0, 0, rad, rad)), (0, 0)) 
    alpha.paste(circle.crop((0, rad, rad, rad * 2)), (0, h - rad)) 
    alpha.paste(circle.crop((rad, 0, rad * 2, rad)), (w - rad, 0)) 
    alpha.paste(circle.crop((rad, rad, rad * 2, rad * 2)), (w - rad, h - rad)) 
    im.putalpha(alpha) 
    return im 

im = Image.open('tiger.jpg') 
im = add_corners(im, 100) 
im.save('tiger.png') 

ejemplo borde curvo tigre:

enter image description here

aquí es su imagen, procesado con este código, dando esquinas transparentes:

enter image description here

+0

gracias, pero todavía tiene una esquina blanca en el fondo. Consulte este [enlace] (http://www.flickr.com/photos/[email protected] N03/7485468218/in/photostream) para ver el problema, y ​​necesito el rincón rosado invisible, en su caso esquina blanca (U no puede verlo aquí ya que es blanco, del mismo color que la página web) .. Espero que entiendas lo que quiero decir – bdictator

+0

@bdictator - por favor publique su código completo. y ¿estás usando mi código y guardando como png? – fraxel

+0

sí, estoy usando tu código, mira mi código agregado – bdictator

0

¿Has probado algo como image.putalpha(mask) para reemplazar el canal alfa de la imagen con la máscara? Parece que debería hacer lo que quieras. mask podría tener que estar en modo 'L' para que esto funcione correctamente, y image probablemente sea 'RGBA', pero podría convertirse automáticamente para usted.

La respuesta más común aquí proporciona algunos buenos ejemplos: How do I generate circular thumbnails with PIL?

Tu imagen de la máscara se ve bien, pero creo que desea intercambiar 'blanco' y 'negro', por lo que tiene un rectángulo redondeado blanco exactamente la forma quieres que tu imagen final sea, sobre un fondo negro. Probablemente también necesitará usar el modo 'L' (escala de grises) uno.

Una vez que tenga esta imagen, puede reemplazar return ImageChops.add(mask, image) por image.putalpha(mask); return image y esto debería causar que la imagen sea transparente solo en las áreas negras de la máscara.

Puede que necesite convertir la imagen primero con image.convert('RGBA'), pero creo que esto no es necesario en versiones posteriores de PIL, lo hace automáticamente.

Algo así como: (lo siento no puede probar esto ahora)

 
def round_corner_jpg(image, radius): 
    """generate round corner for image""" 
    mask = Image.new('L', image.size) # filled with black by default 
    draw = aggdraw.Draw(mask) 
    brush = aggdraw.Brush('white') 
    width, height = mask.size 
    #upper-left corner 
    draw.pieslice((0,0,radius*2, radius*2), 90, 180, None, brush) 
    #upper-right corner 
    draw.pieslice((width - radius*2, 0, width, radius*2), 0, 90, None, brush) 
    #bottom-left corner 
    draw.pieslice((0, height - radius * 2, radius*2, height),180, 270, None, brush) 
    #bottom-right corner 
    draw.pieslice((width - radius * 2, height - radius * 2, width, height), 270, 360, None, brush) 
    #center rectangle 
    draw.rectangle((radius, radius, width - radius, height - radius), brush) 
    #four edge rectangle 
    draw.rectangle((radius, 0, width - radius, radius), brush) 
    draw.rectangle((0, radius, radius, height-radius), brush) 
    draw.rectangle((radius, height-radius, width-radius, height), brush) 
    draw.rectangle((width-radius, radius, width, height-radius), brush) 
    draw.flush() 
    image = image.convert('RGBA') 
    image.putalpha(mask) 
    return image 
+0

, echa un vistazo al enlace que agregué para ver el problema. No creo que el vínculo que di es lo que estoy buscando y no estoy seguro de lo que dijiste sobre cosas alfa. – bdictator

+0

@bdictator el canal "alfa" es la parte de la imagen que contiene la información de transparencia. 'image.putalpha (máscara)' debe reemplazar solo la información de transparencia con la imagen de la máscara, donde el color de la máscara blanca significa opacidad completa (sin transparencia, imagen original) y negro significa transparencia total (totalmente transparente). Intentaré actualizar la respuesta para agregar más detalles. – mesilliac

+0

Muchas gracias, pero parece lo mismo con las cosas blancas en la esquina del fondo – bdictator

Cuestiones relacionadas