Imágenes
Funciones
Image* | image_from_pixels (...) |
Image* | image_from_pixbuf (...) |
Image* | image_from_file (...) |
Image* | image_from_data (...) |
Image* | image_from_resource (...) |
Image* | image_rotate (...) |
Image* | image_scale (...) |
Image* | image_copy (...) |
Image* | image_read (...) |
bool_t | image_to_file (...) |
void | image_write (...) |
void | image_destroy (...) |
void | image_size (...) |
void | image_format (...) |
void | image_pixels (...) |
void | image_codec (...) |
codec_t | image_get_codec (...) |
uint32_t | image_num_frames (...) |
real32_t | image_frame_length (...) |
Una imagen digital, también llamada bitmap o raster graphics, es un conjunto de pequeños puntos de color denominados píxeles organizados en una matriz rectangular. Se caracteriza por su resolución (ancho, alto) y profundidad, que es la cantidad de bits necesaria para codificar cada pixel (Figura 1).
Los imágenes bitmap funcionan mejor para captar instantáneas del mundo real, donde es prácticamente imposible descomponer la escena en bloques geométricos, como vimos en Primitivas de dibujo. Como contrapartida, al estar compuesta por puntos discretos, no se comporta bien ante los cambios de tamaño donde sufrirá una pérdida de calidad.

1. Cargar y visualizar imágenes
En la mayoría de ocasiones, lo único que necesitaremos saber sobre imágenes será como leerlas de disco u otro origen de datos para, posteriormente, visualizarlas en pantalla como parte de la interfaz de usuario (Listado 1) (Figura 2). Consideramos que las imágenes están almacenadas en alguno de los formatos estándar: JPG, PNG, BMP o GIF.
1 2 3 4 5 |
Image *img = image_from_file("lenna.jpg", NULL); Image *icon = image_from_resource(pack, ekCANCEL); ... imageview_image(view, img); button_image(button, icon); |

- Utiliza image_from_file para cargar una imagen de disco.
- Utiliza image_from_data para crear una imagen desde un búfer de memoria.
- Utiliza image_from_resource para obtener una imagen de un paquete de recursos.
- Utiliza image_read para crear una imagen a partir de Streams.
- En Imágenes desde URLs tienes un ejemplo de como descargarlas desde un servidor Web.
NAppGUI solo soporta los formatos JPG, PNG, BMF y GIF.
Una vez cargado el objeto imagen en memoria, disponemos de varias formas de visualizarlo:
- Utiliza draw_image para dibujar una imagen en un contexto 2d.
- Utiliza imageview_image para asignar una imagen a una vista.
- Utiliza button_image para asignar una imagen a un botón.
- Utiliza popup_add_elem para asignar un texto e icono a una lista desplegable.
2. Generar imágenes
Como ya vimos en Contextos 2D, si fuera necesario podemos crear nuestras propias imágenes a partir de primitivas geométricas. En Dibujando en una imagen tienes una aplicación de ejemplo completa (Figura 3).
- Utiliza dctx_image para crear una imagen a partir de un contexto 2d.

3. Acceso a píxeles
Las imágenes son objetos inmutables optimizados para el dibujo recurrente en pantalla, por lo que se permiten ciertas licencias, tanto en la organización interna de la información de color como en la gestión de posibles copias. Por este motivo no es posible manipular directamente los píxeles, sino que debemos acceder a ellos mediante un Pixel Buffer.
- Utiliza image_from_pixels para crear una imagen a partir de la información de color.
- Utiliza image_from_pixbuf para crear una imagen a partir de un pixel búfer.
- Utiliza image_pixels para obtener un búfer con los píxeles de la imagen.
Documentación técnica de Apple: "Treat NSImage and its image representations as immutable objects. The goal of NSImage is to provide an efficient way to display images on the target canvas. Avoid manipulating the data of an image representation directly, especially if there are alternatives to manipulating the data, such as compositing the image and some other content into a new image object."
Los pixel buffers nos permiten de una forma óptima manipular el contenido de la imagen. Para visualizar el resultado o almacenarlo en cualquiera de los formatos soportados, deberemos crear una nueva imagen (Figura 4).

4. Guardar imágenes: Codecs
Uno de los mayores problemas de las imágenes digitales es la gran cantidad de memoria que necesitan. Una imagen de tan solo 1024x768 píxeles y 32bits de color necesita 3 megabytes de memoria. Puede que no parezca mucho, pero a finales de los años 80 esto suponía un gran handicap ya que la memoria era muy cara y las transmisiones muy lentas. Por esto se idearon varios sistemas de codificación (compresión) que reducían la cantidad de memoria necesaria y que se consolidaron con el auge de Internet (Figura 5).
- Utiliza image_get_codec para obtener el codec asociado a la imagen.
- Utiliza image_codec para cambiar el codec asociado a la imagen.
- Utiliza image_to_file para guardarla en disco.
- Utiliza image_write para escribirla en un Stream.
- JPEG: Joint Photographic Experts Group es un formato con una muy buena tasa de compresión basada en la Transformada de Fourier. Ideal para captar instantáneas del mundo real, aunque restará algo de calidad a la captura original (compresión con pérdida).
- PNG: Portable Network Graphics surgió como respuesta a los problemas legales con el formato GIF. Soporta compresión LZ77/Deflate sin pérdida y formatos de píxel indexado. Ideal para esquemas, gráficos o imágenes generadas por computador.
- GIF: Graphics Interchange Format. Utiliza el algoritmo de compresión propietario LZW, aunque la patente expiró en 2003. Ha sobrevivido a PNG gracias a que puede incluir animaciones en un solo archivo, algo que ninguno de los dos formatos anteriores soporta.
- BMP: BitMaP. Formato nativo de Windows ampliamente superado por los otros tres. Aunque soporta un tipo especial de compresión denominado Run-Length encoding, lo cierto es que la mayoría de archivos se guardan sin comprimir. Los archivos BMP ocupan mucho más espacio, por este motivo se utiliza muy poco en Internet y casi nada en máquinas ajenas a Windows. Es soportado por casi todos los programas y sistemas gracias a que es muy sencillo y rápido de interpretar.

Para poder visualizarse en pantalla, la imagen debe ser descomprimida (de-codificada), proceso que se realiza automáticamente al leer la imagen. Al guardarla a disco o enviarla por la red se realiza el proceso contrario, se comprime o codifica utilizando el algoritmo asociado a la misma (Tabla 1), pero se puede cambiar.
Constructor | Codec |
image_from_file | El codec original. |
image_from_data | El codec original. |
image_from_resource | El codec original. |
image_from_pixels | ¿Transparencias? Sí:ekPNG No:ekJPG. |
dctx_image | ekPNG. |
image_from_pixels ()
Crea una imagen a partir de un array de píxeles.
Image* image_from_pixels(const uint32_t width, const uint32_t height, const pixformat_t format, const byte_t *data, const color_t *palette);
width | El ancho de la imagen (en píxeles). |
height | El alto de la imagen (en píxeles). |
format | El formato de pixel. |
data | Búfer que contiene el valor de color de cada pixel. Dependerá de la resolución y del formato. |
palette | Paleta de color necesaria para representar imágenes indexadas. Si es |
Retorna
La imagen recién creada.
Observaciones
Ver Acceso a píxeles.
image_from_pixbuf ()
Crea una imagen a partir de un píxel buffer.
Image* image_from_pixbuf(const Pixbuf *pixbuf, const Palette *palette);
pixbuf | El buffer. |
palette | La paleta. |
Retorna
La imagen recién creada.
Observaciones
Igual a image_from_pixels evitando indicar los parámetros por separado.
image_from_file ()
Crea una imagen a partir de un archivo en disco.
Image* image_from_file(const char_t *pathname, ferror_t *error);
pathname | La ruta del archivo. Filename y pathname. |
error | Código de error si la función falla. Puede ser |
Retorna
La imagen recién creada.
Observaciones
Solo los formatos jpg, png, bmp y gif son aceptados.
image_from_data ()
Crea una imagen a partir de un búfer que contiene los datos codificados.
Image* image_from_data(const byte_t *data, const uint32_t size);
data | El búfer con los datos de la imagen. |
size | El tamaño del búfer en bytes. |
Retorna
La imagen recién creada.
Observaciones
El búfer representa datos codificados en jpg, png, bmp o gif. Para crear la imagen directamente desde píxeles utiliza image_from_pixels.
image_from_resource ()
Obtiene una imagen de un paquete de recursos.
Image* image_from_resource(const ResPack *pack, const ResId id);
pack | El paquete de recursos. |
id | El identificador del recurso. |
Retorna
La imagen.
Observaciones
Ver Recursos.
image_rotate ()
Crea una nueva imagen rotando otra ya existente.
Image* image_rotate(const Image *image, const real32_t angle, const bool_t nsize, const color_t background);
image | La imagen original. |
angle | Ángulo en radianes. |
nsize |
|
background | Color de fondo. La nueva imagen tendrá zonas "en blanco" debido a la rotación. |
Retorna
La imagen recién creada.
image_scale ()
Crea una copia de la imagen, con un nuevo tamaño.
Image* image_scale(const Image *image, const uint32_t nwidth, const uint32_t nheight);
image | La imagen original. |
nwidth | El ancho de la nueva imagen. Pasar UINT32_MAX para que se mantenga la relación de aspecto con respecto a |
nheight | El alto de la nueva imagen. Pasar UINT32_MAX para que se mantenga la relación de aspecto con respecto a |
Retorna
La imagen recién creada.
Observaciones
Si ambos valores nwidth
, nheight
son UINT32_MAX
o las nuevas dimensiones son idénticas a las actuales se incrementará el contador de referencias interno, al igual que ocurre en image_copy.
image_copy ()
Crea una copia de la imagen.
Image* image_copy(const Image *image);
image | La imagen original. |
Retorna
La imagen copiada.
Observaciones
Las imágenes son objetos inmutables. Copiar realmente significa incrementar un contador interno sin llegar a clonar el objeto. No obstante, la aplicación debe destruir la copia con image_destroy al igual que las creadas con cualquier otro constructor. Cuando todas las copias sean destruídas se eliminará realmente de memoria.
image_read ()
Crea una imagen a partir de los datos leídos desde un Streams.
Image* image_read(Stream *stm);
stm | Stream de lectura. Se esperan datos codificados en jpg, png, bmp o gif. La función detecta el formato automáticamente. |
Retorna
La imagen recién creada.
image_to_file ()
Guarda una imagen en disco, utilizado el codec asociado a la misma.
bool_t image_to_file(const Image *image, const char_t *pathname, ferror_t *error);
image | La imagen. |
pathname | La ruta del archivo destino. Filename y pathname. |
error | Código de error si la función falla. Puede ser |
Retorna
TRUE
si se ha guardado correctamente o FALSE
y ha ocurrido algún error.
Observaciones
Utiliza image_codec para cambiar el codec por defecto.
image_write ()
Escribe una imagen en un stream de salida, utilizado el codec asociado a la misma.
void image_write(Stream *stm, const Image *image);
stm | Stream de escritura. Se escribirán datos codificados en jpg, png, bmp o gif. |
image | La imagen. |
Observaciones
Utiliza image_codec para cambiar el codec por defecto.
image_destroy ()
Destruye la imagen.
void image_destroy(Image **image);
image | La imagen. Será puesto a |
image_size ()
Obtiene la resolución de la imagen.
void image_size(const Image *image, uint32_t *width, uint32_t *height);
image | La imagen. |
width | El ancho de la imagen en píxeles. |
height | El alto de la imagen en píxeles. |
image_format ()
Obtiene el formato de pixel de la imagen.
void image_format(const Image *image, pixformat_t *format);
image | La imagen. |
format | El formato de pixel. |
image_pixels ()
Obtiene un búfer con los píxeles que forman la imagen decodificada.
void image_pixels(const Image *image, const pixformat_t format, Pixbuf **pixels, Palette **palette);
image | La imagen. |
format | El formato de pixel requerido. |
pixels | El búfer donde se almacenará el resultado. Debe ser destruido con pixbuf_destroy. |
palette | La paleta de color en caso de imágenes indexadas. Debe ser destruida con palette_destroy. Puede ser |
Observaciones
Si en pixformat
indicamos ekOPTIMAL se utilizará el formato que menos bits requiera sin pérdida de información. ekFIMAGE utilizará el formato original de la imagen. Para cualquier otro valor se realizará la conversión si fuera necesario.
image_codec ()
Cambia el codec por defecto asociado con la imagen.
void image_codec(const Image *image, const codec_t codec);
1 2 3 4 |
Image *img = image_from_file("lenna.jpg", NULL); Stream *stm = stm_socket(ip, port, NULL, NULL); image_codec(img, ekPNG); image_write(socket, img); |
image | La imagen. |
codec | El nuevo codec. |
Observaciones
El cambio tendrá efecto la próxima vez que guardemos o escribamos la imagen. Por defecto, la imagen conserva el codec con el que fue leída. Cuando la creamos con image_from_pixels se le asigna el codec ekJPG por defecto. Para imágenes desde contextos 2d dctx_image, el codec por defecto es ekPNG.
image_get_codec ()
Obtiene el codec asociado con la imagen.
codec_t image_get_codec(const Image *image);
image | La imagen. |
Retorna
El codec.
Observaciones
Ver image_codec.
image_num_frames ()
Obtiene el número de secuencias en imágenes animadas.
uint32_t image_num_frames(const Image *image);
image | La imagen. |
Retorna
El número de secuencias o frames.
Observaciones
Únicamente el formato gif soporta animaciones. Para el resto siempre se devolverá 1.
image_frame_length ()
Obtiene el tiempo que dura una secuencia de animación.
real32_t image_frame_length(const Image *image, const uint32_t findex);
image | La imagen. |
findex | El índice del frame. |
Retorna
El tiempo de la secuencia en segundos.
Observaciones
Únicamente el formato gif soporta animaciones.