SDK Multiplataforma en C logo

SDK Multiplataforma en C

Pixel Buffer

❮ Anterior
Siguiente ❯

Funciones

Pixbuf*pixbuf_create (...)
Pixbuf*pixbuf_copy (...)
Pixbuf*pixbuf_trim (...)
Pixbuf*pixbuf_convert (...)
voidpixbuf_destroy (...)
pixformat_tpixbuf_format (...)
uint32_tpixbuf_width (...)
uint32_tpixbuf_height (...)
uint32_tpixbuf_size (...)
uint32_tpixbuf_dsize (...)
const byte_t*pixbuf_cdata (...)
byte_t*pixbuf_data (...)
uint32_tpixbuf_format_bpp (...)
uint32_tpixbuf_get (...)
voidpixbuf_set (...)

Un pixel buffer (Pixbuf) es una área de memoria que representa una rejilla discreta de puntos de color. Permiten el acceso directo a la información pero no están optimizados para el dibujo en pantalla, por lo que deberemos crear un objeto Image para poder visualizarlos. Son muy eficientes para la generación procedimental de imágenes o la aplicación de filtros, ya que leer o escribir un valor no requiere más que acceder a su posición dentro del búfer.

Todas las operaciones sobre pixel buffers se realizan en la CPU. Son eficientes en la medida que accedemos directamente a memoria, pero no se pueden comparar con alternativas que utilicen la GPU para el procesamiento digital de imágenes.

1. Formatos de píxel

El formato hace referencia a como se codifica el valor de cada píxel dentro del búfer (Tabla 1) (Figura 1).

  • Utiliza pixbuf_format para obtener el formato del píxel.
  • Utiliza pixbuf_format_bpp para obtener el número de bits queridos por cada píxel.
  • Tabla 1: Formatos de pixel.
    Valor Descripción
    ekRGB24 True color +16 Millones simultáneos, 24 bits por píxel.
    ekRGBA32 True color con canal alpha (transparencias), 32 bits por píxel.
    ekGRAY8 256 tonos de gris, 8 bits por píxel.
    ekINDEX1 Indexado, 1 bit por pixel.
    ekINDEX2 Indexado, 2 bits por pixel.
    ekINDEX4 Indexado, 4 bits por pixel.
    ekINDEX8 Indexado, 8 bits por pixel.
    Diferentes arrays de bytes con datos de píxeles.
    Figura 1: Formatos de píxel: (a) Color real, (b) tonos de gris, (c) indexados.

2. Imágenes procedimentales

Una forma de "rellenar" los buffers es mediante algoritmos que calculen el valor de cada píxel. Un claro ejemplo de imágen procedimental lo puedes encontrar en Fractals (Figura 2), una aplicación enfocada en la representación de conjuntos fractales, un área de la matemática dedicada al estudio de determinados sistemas dinámicos.

  • Utiliza pixbuf_data para obtener un puntero al contenido del búfer.
  • Utiliza pixbuf_set para escribir el valor de un píxel.
  • Utiliza pixbuf_get para leer el valor de un píxel.
  • Representación de un conjunto de Julia.
    Figura 2: Conjunto de Julia. Imagen generada píxel a píxel mediante algoritmos fractales.

Si bien pixbuf_set y pixbuf_get permiten la manipulación segura de píxeles, en ocasiones puede ser necesario obtener un extra en cuanto a rendimiento se refiere. En (Listado 1) tenemos algunas macros para el acceso directo al área de memoria devuelta por pixbuf_data. Utilizalas con sumo cuidado y sabiendo lo que haces, ya que no disponen de métodos de control de errores, por lo que es probable que se produzcan fallos de segmentación si no se usan correctamente.

Listado 1: Macros rápidas para la manipulación de un búfer tipo ekINDEX1 (1 bit por pixel).
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#define pixbuf_get1(data, x, y, w)\
    (uint32_t)((data[((y)*(w)+(x))/8] >> (byte_t)(((y)*(w)+(x))%8)) & 1)

#define pixbuf_set1(data, x, y, w, v)\
{\
    register byte_t *__ob = data + (((y)*(w))+(x))/8;\
    register byte_t __op = (byte_t)((((y)*(w))+(x))%8);\
    *__ob &= ~(1 << __op);\
    *__ob |= ((v) << __op);\
}

3. Copia y conversión

Durante el procesamiento digital de una imagen es posible que tengamos que encadenar varias operaciones, por lo que será de utilidad poder realizar copias de los búfer o conversiones de formato.

  • Utiliza pixbuf_copy para realizar una copia.
  • Utiliza pixbuf_convert para convertir entre formatos (Tabla 2).
  • Tabla 2: Conversión entre formatos.
    Desde Hacia Observaciones
    RGB24 RGB32 Se añade canal alfa con el valor 255
    RGB32 RGB24 Se elimina el canal alfa con posible pérdida de información.
    RGB(A) Gray Se ponderan los canales RGB a razón de 77/255, 148/255, 30/255. Se pierde el canal alfa.
    Gray RGB(A) Se duplican los canales RGB(gray, gray, gray). Canal alfa a 255.
    RGB(A) Indexed Se calcula la menor distancia entre cada píxel y la paleta. Posible pérdida de información.
    Indexed RGB(A) Se utilizará la paleta para obtener cada valor RGBA.
    Indexed Indexed Si el destino tiene menor número de bits, se aplicará out = in % bpp con posible pérdida de información.
    Gray Indexed El formato Gray8 se considerará indexado a todos los efectos.
    Indexed Gray El formato Gray8 se considerará indexado a todos los efectos.

pixbuf_create ()

Crea un nuevo pixel búfer.

Pixbuf*
pixbuf_create(const uint32_t width,
              const uint32_t height,
              const pixformat_t format);
width

Anchura.

height

Altura.

format

Formato de píxel.

Retorna

El píxel búfer.

Observaciones

El contenido inicial estará indeterminado.


pixbuf_copy ()

Crea una copia del pixel búfer.

Pixbuf*
pixbuf_copy(const Pixbuf *pixbuf);
pixbuf

El búfer original.

Retorna

La copia.


pixbuf_trim ()

Recorta un pixel búfer.

Pixbuf*
pixbuf_trim(const Pixbuf *pixbuf,
            const uint32_t x,
            const uint32_t y,
            const uint32_t width,
            const uint32_t height);
pixbuf

El búfer original.

x

Coordenada x del pixel superior-izquierda.

y

Coordenada y del pixel superior-izquierda.

width

Número de píxeles de ancho.

height

Número de píxeles de alto.

Retorna

Un nuevo pixel búfer con el recorte.

Observaciones

La función no comprueba que los límites sean válidos. Obtendrás un error de segmentación en dichos casos.


pixbuf_convert ()

Cambia el formato de un píxel búfer.

Pixbuf*
pixbuf_convert(const Pixbuf *pixbuf,
               const Palette *palette,
               const pixformat_t oformat);
pixbuf

El búfer original.

palette

Paleta de colores necesaria para determinadas conversiones.

oformat

Formato del búfer resultado.

Retorna

El búfer convertido.

Observaciones

Ver Copia y conversión.


pixbuf_destroy ()

Destruye el búfer.

void
pixbuf_destroy(Pixbuf **pixbuf);
pixbuf

El búfer. Será puesto a NULL tras la destrucción.


pixbuf_format ()

Obtiene el formato de píxel.

pixformat_t
pixbuf_format(const Pixbuf *pixbuf);
pixbuf

El búfer.

Retorna

El formato.

Observaciones

Ver Formatos de píxel.


pixbuf_width ()

Obtiene la anchura del búfer.

uint32_t
pixbuf_width(const Pixbuf *pixbuf);
pixbuf

El búfer.

Retorna

Anchura.


pixbuf_height ()

Obtiene la altura del búfer.

uint32_t
pixbuf_height(const Pixbuf *pixbuf);
pixbuf

El búfer.

Retorna

Altura.


pixbuf_size ()

Obtiene el tamaño del búfer (en píxeles).

uint32_t
pixbuf_size(const Pixbuf *pixbuf);
pixbuf

El búfer.

Retorna

Anchura x altura.


pixbuf_dsize ()

Obtiene el tamaño del búfer (en bytes).

uint32_t
pixbuf_dsize(const Pixbuf *pixbuf);
pixbuf

El búfer.

Retorna

Número de bytes totales del búfer.


pixbuf_cdata ()

Obtiene un puntero de solo lectura al contenido del búfer.

const byte_t*
pixbuf_cdata(const Pixbuf *pixbuf);
pixbuf

El búfer.

Retorna

Puntero al primer elemento.

Observaciones

Manipular correctamente el búfer requiere conocer los Formatos de píxel y, en ocasiones, utilizar los operadores a nivel de bit. Utilizar pixbuf_get para leer correctamente un píxel.


pixbuf_data ()

Obtiene un puntero de lectura/escritura al contenido del búfer.

byte_t*
pixbuf_data(Pixbuf *pixbuf);
pixbuf

El búfer.

Retorna

Puntero al primer elemento.

Observaciones

Manipular correctamente el búfer requiere conocer los Formatos de píxel y, en ocasiones, utilizar los operadores a nivel de bit. Utilizar pixbuf_get y pixbuf_set para leer/escribir correctamente un píxel.


pixbuf_format_bpp ()

Obtiene los bits por píxel según el formato.

uint32_t
pixbuf_format_bpp(const pixformat_t format);
format

El formato.

Retorna

Bits por píxel.

Observaciones

Ver Formatos de píxel.


pixbuf_get ()

Obtiene el valor de un píxel.

uint32_t
pixbuf_get(const Pixbuf *pixbuf,
           const uint32_t x,
           const uint32_t y);
pixbuf

El búfer.

x

Coordenada x del píxel.

y

Coordenada y del píxel.

Retorna

El valor.

Observaciones

Ver Formatos de píxel para interpretar correctamente el valor.


pixbuf_set ()

Establece el valor de un píxel.

void
pixbuf_set(Pixbuf *pixbuf,
           const uint32_t x,
           const uint32_t y,
           const uint32_t value);
pixbuf

El búfer.

x

Coordenada x del píxel.

y

Coordenada y del píxel.

value

El valor.

Observaciones

Ver Formatos de píxel para interpretar correctamente el valor.

❮ Anterior
Siguiente ❯