2012-08-17 30 views
5

Estoy marcando con aguamarina algunas imágenes usando PIL y estoy teniendo dificultades para leer parte del texto (texto negro sobre fondo oscuro). No puedo simplemente cambiar el color del texto ya que tengo una amplia gama de colores de fondo. ¿Hay alguna manera de agregar un efecto halo alrededor del texto?Crear un halo alrededor del texto en Python usando PIL?

Por ejemplo: http://i.imgur.com/WYxSU.jpg El texto de abajo es lo que tengo, y el texto de arriba es lo que espero obtener (colores a un lado). Realmente solo necesito un contorno delgado alrededor del texto. ¿Algunas ideas? Puedo cargar algún código si realmente crees que hará la diferencia, pero es solo un comando PIL ImageDraw.Draw normal. ¡Gracias!

+1

Imprima el texto tres veces. Los primeros dos con el color de contorno y las compensaciones de (-1, -1) y (1, 1) y el tercero con el color original en la posición original. – Matthias

+2

http://mail.python.org/pipermail/image-sig/2009-May/005681.html http://stackoverflow.com/a/8050556/442650 –

+0

PIL.ImageDraw tiene una opción 'outline', pero no es válido para texto –

Respuesta

7

Si no se preocupan por la velocidad demasiado, se puede hacer uso de la composición: Texto

  1. empate con el halo de color en la imagen en blanco RGBA
  2. desenfoque que
  3. dibujar de nuevo con el color del texto
  4. invertido esta imagen para obtener la composición máscara
  5. "Combinar" imagen original con

Por ejemplo:

import sys 
import Image, ImageChops, ImageDraw, ImageFont, ImageFilter 

def draw_text_with_halo(img, position, text, font, col, halo_col): 
    halo = Image.new('RGBA', img.size, (0, 0, 0, 0)) 
    ImageDraw.Draw(halo).text(position, text, font = font, fill = halo_col) 
    blurred_halo = halo.filter(ImageFilter.BLUR) 
    ImageDraw.Draw(blurred_halo).text(position, text, font = font, fill = col) 
    return Image.composite(img, blurred_halo, ImageChops.invert(blurred_halo)) 

if __name__ == '__main__': 
    i = Image.open(sys.argv[1]) 
    font = ImageFont.load_default() 
    txt = 'Example 1234' 
    text_col = (0, 255, 0) # bright green 
    halo_col = (0, 0, 0) # black 
    i2 = draw_text_with_halo(i, (20, 20), txt, font, text_col, halo_col) 
    i2.save('halo.png') 

Tiene muchas ventajas:

  • el resultado es suave y se ve bien
  • se puede elegir filtro diferente en lugar de BLUR para obtener diferentes "halo"
  • funciona incluso con fuentes muy grandes y aún se ve muy bien

Para obtener más gruesas de halo, se pueden usar filtro de la siguiente manera:

kernel = [ 
    0, 1, 2, 1, 0, 
    1, 2, 4, 2, 1, 
    2, 4, 8, 4, 1, 
    1, 2, 4, 2, 1, 
    0, 1, 2, 1, 0] 
kernelsum = sum(kernel) 
myfilter = ImageFilter.Kernel((5, 5), kernel, scale = 0.1 * sum(kernel)) 
blurred_halo = halo.filter(myfilter) 

La parte scale = 0.1 * sum(kernel) hace que el halo más gruesa (valores pequeños) o dimmer (valores grandes).

+0

Creo que un esquema adecuado se vería mejor en este caso, como en el ejemplo de la pregunta, pero esta es la forma correcta de generar un "halo". El único inconveniente es que cuanto más ancho haces el halo, más oscuro se vuelve. Estoy un poco decepcionado de que PIL no ofrezca una manera más directa de combinar una imagen RGBA con otra. –

+0

Cool gracias. Solo una pregunta ... el desenfoque es muy borroso ... con texto negro y desenfoque blanco ... el desenfoque de hecho resulta invisible sobre un fondo negro. ¿Cómo podemos agudizar esto? Tal vez eso es lo que quieres decir con un halo más grueso. – Jonny

+0

@Jonny sí, probablemente sea eso. O bien, puede usar un filtro diferente (consulte: http://pillow.readthedocs.org/en/latest/reference/ImageFilter.html), juegue con los valores * scale * o * offset * en http://pillow.readthedocs.org/en/latest/reference/ImageFilter.html#PIL.ImageFilter.Kernel –

Cuestiones relacionadas