Pixel Buffer
Funciones
Pixbuf* | pixbuf_create (...) |
Pixbuf* | pixbuf_copy (...) |
Pixbuf* | pixbuf_trim (...) |
Pixbuf* | pixbuf_convert (...) |
void | pixbuf_destroy (...) |
pixformat_t | pixbuf_format (...) |
uint32_t | pixbuf_width (...) |
uint32_t | pixbuf_height (...) |
uint32_t | pixbuf_size (...) |
uint32_t | pixbuf_dsize (...) |
const byte_t* | pixbuf_cdata (...) |
byte_t* | pixbuf_data (...) |
uint32_t | pixbuf_format_bpp (...) |
uint32_t | pixbuf_get (...) |
void | pixbuf_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.
- Utiliza pixbuf_create para crear un píxel búfer.
- Utiliza pixbuf_trim para recortar un píxel búfer.
- Utiliza pixbuf_width para obtener la anchura de la rejilla.
- Utiliza pixbuf_height para obtener la altura de la rejilla.
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.
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. |
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.
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.
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).
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 |
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.