Publi

Leer y procesar imágenes en C gracias a ImageMagick y su API MagickCore


El mundo de la imagen por ordenador me encanta, y llega el momento de aplicar ciertos efectos desde código, y evitarnos tener que ejecutar un programa externo, gastando así más memoria y tiempo. Pero por otro lado, en ocasiones algunos algoritmos sobre las imágenes son demasiado complejos y no tenemos tiempo para investigar cómo hacer el algoritmo, buscar especificaciones de efectos que suelen traer todos los programas de edición de imágenes, pero que nos pueden hacer perder varios días de trabajo de investigación. Es más, la simple apertura de un fichero de imagen es muy dura si la hacemos a pelo

Ahí entra ImageMagick, del que he hablado en algunas ocasiones y he puesto muchos ejemplos. Es un software muy ligero con el que podemos editar nuestras fotografías desde la línea de comandos; pero además tiene una API muy potente, MagickCore, aunque tenemos otras APIs y bindings para otros lenguajes.

En este caso, si queremos tener más potencia, podríamos utilizar la interacción con GIMP, esto nos daría una potencia mucho más grande, pero efectos sencillos (dentro de lo que cabe) serían muy lentos y deberíamos tener The Gimp cargado en memoria (y es bastante grande). Utilizar ImageMagick nos da sencillez para aplicar muchos efectos, y a su vez un consumo de memoria y CPU razonable.

No pretendo hacer nada excesivamente complicado, y un ejemplo parecido a este lo podréis encontrar en muchas webs, por lo que sólo pretendo hacer una introducción, la API es extensa y tiene muchísimas funciones sobre imágenes que podemos combinar, lo que nos da bastante potencia.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <stdlib.h>
#include <magick/MagickCore.h>
#include <string.h>

int main()
{
  Image *im;
  ExceptionInfo *exception;
  ImageInfo *imInfo;
  Image *out;
 
  // Cargamos el archivo de imagen
  imInfo =CloneImageInfo((ImageInfo*)NULL);
  exception = AcquireExceptionInfo();
  strcpy(imInfo->filename, "acueducto_nerja.jpg");
  im = ReadImage(imInfo, exception);

  // Verificamos si hay errores
  CatchException(exception);
  if (im==NULL)
    {
      fprintf(stderr, "No tengo imagen\n");
      exit(1);
    }

  // Aplicamos el efecto
  out=CharcoalImage(im, 10.0, 12.0, exception);

  // Salvamos el archivo
  strcpy(out->filename, "acueducto_charcoal.jpg");
  WriteImage(imInfo, out);

  // Liberamos memoria y cerramos la API
  exception=DestroyExceptionInfo(exception);
  im = DestroyImage(im);
  out = DestroyImage(out);
  imInfo = DestroyImageInfo(imInfo);
  MagickCoreTerminus();

  return 0;
}

Como vemos, tenemos una estructura destinada al almacén de imágenes, y funciones para abrir la imagen fácilmente, así como para salvarla, ya se encarga MagickCore de buscar la forma de abrir los archivos y guardarlos, así como de aplicar el efecto deseado.

Muy importante liberar memoria y cerrar la API cuando vayamos a dejar de utilizarla, ¡tenemos que escribir buen código! (dentro de lo que cabe).

Por otro lado, podemos utilizar la variable exception para enterarnos de los errores que puedan ocurrir en el transcurso del programa, aunque CatchException() continuará la ejecución y tendremos que ser nosotros (como en el ejemplo), los que tomemos la decisión de qué hacer, en este caso, salir del programa, pero podríamos hacer cualquier otra cosa, como escribir un log, por ejemplo. Aunque si llamamos a CatchException() y no ha pasado nada, no mostrará nada por pantalla.

De todas formas, si falla al abrir la imagen, todo lo demás también debería fallar, ya que no hay imagen para operar.

Para saber si hay una excepción o no, podemos probar su propiedad severity de la siguiente forma:

1
2
if (exception->severity != UndefinedException)
   printf ("Hay un error: %s!!\n", exception->reason);

Por último, para compilar, debemos hacerlo con las opciones de Magick-config:

$ gcc magicktest.c -o magicktest.c `Magick-config –libs` `Magick-config –cflags`

Foto: María Herrero (Acueducto del Águila, en Nerja)

También podría interesarte...

Leave a Reply