Agregando texto a imágenes con PIL

Este es un post netamente técnico (o sea aburrido :-D).

En ocasiones puede ser útil agregar texto a una serie de imágenes en forma automatizada, evitando el tedioso proceso de agregarlo a mano (y el aún más tedioso de agregarlo de vuelta cuando descubrimos que nos equivocamos). Sabía (a través de John Walker) que pueden utilizarse para este fin las herramientas para línea de comandos Netpbm pero, si estamos trabajando en un script, estas herramientas pueden ser algo inflexibles e incómodas de llamar.

Mientras armaba uno de los posts anteriores descubrí a PIL (Python Imaging Library) que permite realizar estas operaciones en forma relativamente natural desde Python. Por ejemplo, dibujar texto centrado en un rectángulo puede hacerse mediante la siguiente función:

import ImageFont

def draw_centered_text(im_draw, text, r, font_name, color):
    font = ImageFont.truetype(font_name + '.ttf',
                              r[3] - r[1])
    text_size = font.getsize(text)
    if text_size[0] > r[2] - r[0]:
        new_font_height = (r[3] - r[1]) * (r[2] - r[0]) /\
                          text_size[0]
        font = ImageFont.truetype(font_name + '.ttf',
                                  new_font_height)
        text_size = font.getsize(text)
    im_draw.text(((r[2] + r[0]) / 2 - text_size[0] / 2,
                  (r[3] + r[1]) / 2 - text_size[1] / 2),
                 text, font=font, fill=color)

donde im_draw es un objeto del tipo ImageDraw, representando a la imagen sobre la que trabajamos, text es el texto a dibujar, r es una tupla de 4 puntos representando al rectángulo donde irá encerrado el texto (izquierda, arriba, derecha, abajo), font_name es el nombre del archivo TTF con la fuente a utilizar y color es un tupla representando el color del texto a dibujar (RGB).

Un ejemplo de llamada a la función anterior sería:

import Image, ImageDraw

im = Image.open('banner_start.png')
draw = ImageDraw.Draw(im)
draw_centered_text(draw, 'Text', (0, 0, 150, 150),
                   'arial', (0, 0, 0))
draw_centered_text(draw, 'Text', (250, 50, 500, 100),
                   'arial', (255, 0, 0))
im.save('banner_end.png')

Si tomamos a la siguiente imagen como entrada:

Esta imagen, correspondiendo a 'banner_start.png' en el ejemplo, consiste en un cuadrado amarillo en (0, 0) - (150, 150) y un rectángulo celeste en (250, 50) - (500, 100).

Esta imagen, correspondiendo a 'banner_start.png' en el ejemplo, consiste en un cuadrado amarillo en (0, 0) - (150, 150) y un rectángulo celeste en (250, 50) - (500, 100).

obtendremos a la siguiente imagen como salida:

Esta imagen corresponde a 'banner_end.png' en el ejemplo y muestra como el texto se expande lo máximo posible sin perder su relación de aspecto.

Esta imagen corresponde a 'banner_end.png' en el ejemplo y muestra como el texto se expande lo máximo posible sin perder su relación de aspecto.

Espero que pueda serle útil a alguno de los lectores 😉

Advertisements

9 thoughts on “Agregando texto a imágenes con PIL

  1. […] Junio 18, 2009 at 2:17 am (misc, python) (Continuación de Agregando texto a imágenes con PIL.) […]

  2. sixto says:

    al ejecutar el scrittp me emite el siguiente mensaje de error python 2.66, tengo instalado pygame y PIL para esta version
    Traceback (most recent call last):
    File “C:/Python26/otorpil”, line 24, in
    ‘arial’, (0, 0, 0))
    File “C:/Python26/otorpil”, line 7, in draw_centered_text
    r[3] – r[1])
    File “C:\Python26\lib\site-packages\PIL\ImageFont.py”, line 218, in truetype
    return FreeTypeFont(filename, size, index, encoding)
    File “C:\Python26\lib\site-packages\PIL\ImageFont.py”, line 134, in __init__
    self.font = core.getfont(file, size, index, encoding)
    File “C:\Python26\lib\site-packages\PIL\ImageFont.py”, line 34, in __getattr__
    raise ImportError(“The _imagingft C module is not installed”)
    ImportError: The _imagingft C module is not installed
    me gustaria que me ayudaras a encontrar el error.gracias de antenmano

  3. sixto says:

    quisiera que me ayudaran, ya que ejeuto el script para insertar texto en una imagen y me produce el siguiente error:

    Traceback (most recent call last):
    File “C:/Python26/fuenteenimagenPIL”, line 23, in
    ‘arial’, (0, 0, 0))
    File “C:/Python26/fuenteenimagenPIL”, line 6, in draw_centered_text
    r[3] – r[1])
    File “C:\Python26\lib\site-packages\PIL\ImageFont.py”, line 218, in truetype
    return FreeTypeFont(filename, size, index, encoding)
    File “C:\Python26\lib\site-packages\PIL\ImageFont.py”, line 134, in __init__
    self.font = core.getfont(file, size, index, encoding)
    File “C:\Python26\lib\site-packages\PIL\ImageFont.py”, line 34, in __getattr__
    raise ImportError(“The _imagingft C module is not installed”)
    ImportError: The _imagingft C module is not installed y quisiera saber por k.

  4. sixto says:

    si esta el archivo, y aun asi me marca el error anterior

    • mchouza says:

      Fijate si el problema se resuelve al agregar, encima de tu script, las siguientes dos líneas:

      import sys
      sys.path.append('C:\\Python26\\lib\\site-packages\\PIL')
      
  5. Francisco says:

    Buenas tengo este problema:
    Python version 2.6.6

    >>> draw_centered_text(draw, ‘Text’, (0, 0, 150, 150),
    … ‘arial’, (0, 0, 0))
    Traceback (most recent call last):
    File “”, line 2, in
    File “”, line 3, in draw_centered_text
    File “/usr/lib/python2.6/dist-packages/PIL/ImageFont.py”, line 218, in truetype
    return FreeTypeFont(filename, size, index, encoding)
    File “/usr/lib/python2.6/dist-packages/PIL/ImageFont.py”, line 134, in __init__
    self.font = core.getfont(file, size, index, encoding)
    IOError: cannot open resource

    • mchouza says:

      Para que funcione necesitás pasarle como font_name el nombre/path de un archivo .ttf si la extensión. Supongo que el problema en este caso debe ser que, como estás en Linux, no tenés instalada la fuente Arial.

      Para resolver el problema podés copiar el archivo arial.ttf al directorio del script o algun otro archivo .ttf, modficando en ese último caso font_name en la forma correspondiente.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s