Redimensionando una imagen

Posted · Añadir comentario

02-sacerdotisa-detalle

Si queremos trabajar exclusivamente en un fragmento de una imagen, o queremos redimensionarla, ampliar o reducir su tamaño, la forma más sencilla de trabajar consiste en leer los pixeles de la matriz original y copiar aquellos que vamos a utilizar en una nueva matriz que tenga el tamaño deseado. En este tipo de situación trabajamos con dos imágenes o matrices de pixeles, la fuente y el resultado, que generalmente tienen tamaños diferentes, una es mas grande que la otra, por lo que o bien es necesario duplicar pixeles, cuando la imagen resultado es mas grande, o bien es necesario saltarse algunos de los pixeles, cuando la imagen resultado es mas pequeña.

matrices

La solución ideal para este tipo de casos consiste en realizar algunos cálculos llamados interpolaciones que permiten introducir pixeles con valores intermedios en la nueva imagen o obtener una valor medio de los pixeles que no utilizamos. Sin embargo, en muchas ocasiones duplicar o saltarse pixeles ofrece un resultado suficientemente correcto y basta con leer los datos de la imagen fuente mientras recorremos la matriz de la imagen resultado para realizar el trabajo.

interpolaciones

Si empleamos el sistema que utilizamos en el ejercicio anterior para recorrer la matriz de la imagen resultado pixel a pixel y obtener su posición x e y, resulta bastante sencillo calcular la posición que corresponde a ese pixel en la imagen fuente haciendo el cálculo inverso. Basta con sumar el margen lateral izquierdo a la coordenada x y el margen superior a la coordenada, si estamos realizando un recorte, y hacer el siguiente cálculo: [numero de lineas recorridas * ancho de la imagen fuente + posición por la que vamos en la linea actual].

for (int i=0; i<pixelesResultado; i++) {
        int x = i % (anchoResultado * 3);
        int y = (i - x) / ( anchoResultado * 3);
        x += margenIzquierdo*3;
        y += margenSuperior;
        int nuevaPosicion = (y * anchoFuente * 3 + x);
}

¿Es posible evitar realizar este trabajo? Sí, en lugar de hacerlo nosotros, podemos pedirle a la tarjeta gráfica que lo haga. Imaginemonos que pudiésemos dibujar la imagen fuente ampliándola o reduciéndola de tamaño, haciendo incluso que parte de la imagen quede fuera de la pantalla de modo que solamente sea visible el fragmento que queramos utilizar. Si pudiéramos hacerlo y ademas consiguiésemos capturar la pantalla y almacenarla en una nueva matriz, habríamos realizado el trabajo sin hacer casi ningún esfuerzo. Eso es precisamente lo que permite hacer un FBO (Frame Buffer Object), dibujar en un objeto como si lo hiciésemos en la pantalla y reutilizar después el conjunto de pixeles dibujados.

// declaración
ofFbo fbo; // Frame buffer object
ofPixels pixeles; // objecto para almacenar y copiar pixeles
ofTexture texture; // Textura o imagen original
ofTexture newTexture; // Textura resultante

...

// asignacion de memoria  
texture.allocate(antiguoAncho, antiguoAlto, GL_RGB);    
newTexture.allocate(nuevoAncho, nuevoAlto, GL_RGB);        
fbo.allocate(nuevoAncho, nuevoAlto, GL_RGB, 0);

...

// redimensionado
fbo.begin();
texture.draw(0, 0, nuevoAncho, nuevoAlto); // tambien se puede dibujar la imagen mas grande para hacer un recorte
fbo.end();
fbo.readToPixels(pixeles);
newTexture.loadData(pixeles.getPixels(), nuevoAncho, nuevoAlto, GL_RGB);

La gran ventaja de esta nueva estrategia es que la tarjeta gráfica esta diseñada para realizar este tipo de trabajo, por lo que el proceso resultará mucho mas eficiente. Pero además, podremos controlar la forma en que se calculan pixeles que antes simplemente duplicábamos o nos saltábamos, sin necesidad de hacer ningún trabajo, bastará indicarle previamente a la tarjeta gráfica el tipo de interpolaciones que queremos que haga con la textura que dibujemos.

texture.setTextureMinMagFilter(GL_NEAREST, GL_NEAREST);
 
 

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies