es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Añadir un canal alfa a una imagen con PIL.

Tienes una imagen transparente ‘img_rgb_pil’ de tamaño (505,503,4) que deseas recortar de forma ‘circular’. Para esto, estás utilizando esta función:

def to_circular_image(img_rgb_pil): 
   npImage=np.array(img_rgb_pil)
   h,w=img_rgb_pil.size

   # Crear capa alpha del mismo tamaño con círculo
   alpha = Image.new('L', img_rgb_pil.size, 0)
   draw = ImageDraw.Draw(alpha)
   draw.pieslice([0,0,h,w], 0, 360, fill=255)

   # Convertir la imagen alpha en un arreglo de numpy
   npAlpha=np.array(alpha)

   # Agregar la capa alpha a la imagen RGB
   npImage=np.dstack((npImage,npAlpha))

   # Guardar con alpha
   return Image.fromarray(npImage) #<---- TypeError: Cannot handle this data type: (1, 1, 5), |u1

Al llamar a esta función, obtengo el error “TypeError: Cannot handle this data type: (1, 1, 5), |u1”. Entiendo que PIL no puede transformar un arreglo de tamaño (x,y,5) a una imagen PIL. Sin embargo, no sé cómo recortar una imagen circular en una imagen transparente.

Esto es lo que obtengo con la respuesta de abajo:

Imagen de entrada: imagen transparente de entrada
Imagen de salida: resultado

¿Alguna ayuda, por favor?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para recortar una imagen transparente circularmente, puedes modificar la función dada de la siguiente manera:

    from PIL import Image, ImageDraw
    import numpy as np
    
    def to_circular_image(img_rgb_pil): 
        # Convertir imagen PIL a arreglo numpy
        npImage = np.array(img_rgb_pil)
        h, w, d = npImage.shape
    
        # Crear capa alpha del mismo tamaño con forma de círculo
        alpha = Image.new('L', img_rgb_pil.size, 0)
        draw = ImageDraw.Draw(alpha)
        draw.pieslice([0, 0, h, w], 0, 360, fill=255)
    
        # Convertir imagen alpha a arreglo numpy
        npAlpha = np.array(alpha)
        npAlpha = npAlpha[:, :, np.newaxis]
    
        # Agregar capa alpha a la imagen RGB
        npImage = np.concatenate((npImage, npAlpha), axis=2)
    
        # Crear máscara para recorte circular
        centro = (h//2, w//2)
        radio = min(h, w)//2
        Y, X = np.ogrid[:h, :w]
        distancia_desde_centro = np.sqrt((X - centro[1])**2 + (Y - centro[0])**2)
        mascara = distancia_desde_centro <= radio
        mascara = mascara.astype(np.uint8) * 255
    
        # Aplicar máscara a la imagen resultante
        npOutput = np.zeros_like(npImage)
        npOutput[:, :, :d+1] = npImage[:, :, :d+1] 
        npOutput[:, :, -1] = mascara
        npOutput = npOutput.astype(np.uint8)
    
        # Convertir arreglo numpy a imagen PIL y recortar
        output = Image.fromarray(npOutput)
        output = output.crop((centro[1]-radio, centro[0]-radio, centro[1]+radio, centro[0]+radio))
    
        return output
    

    Esta función crea una máscara circular basada en las dimensiones de la imagen de entrada y la aplica a la imagen resultante. Luego, recorta la imagen de salida de manera circular utilizando el centro de la imagen de entrada como centro del círculo y la mínima dimensión de la imagen de entrada como radio.

    Para usar esta función, simplemente llámala con tu imagen transparente:

    img = Image.open("transparent_image.png")
    output = to_circular_image(img)
    output.show()
    

    Esto debería producir una imagen de salida recortada de forma circular según lo deseado.

Comments are closed.