Ver Mensaje Individual
  #1 (permalink)  
Antiguo 02/08/2011, 21:53
Avatar de zero_master
zero_master
 
Fecha de Ingreso: junio-2011
Ubicación: Leon, Gto
Mensajes: 290
Antigüedad: 13 años, 5 meses
Puntos: 74
Procesamiento de imágenes en android

Saludos gente, ya tiene rato que no venia por estos lados; acabo de regresar a clases y puros exámenes pendientes y la tesis en camino , pero bueno aun así aquí estamos.

Me gustaría saber a cuantas personas les gustaría empezar con un mini grupito haciendo publicaciones sobre procesamiento de imágenes en android, algo así como tener una aplicación en baja escala de las funciones clásicas de algunos programas comerciales de manipulación de imágenes.

Para iniciar ya hice algunas aplicaciones en este foro sobre la lectura del RGB de una imagen si necesitan ayuda digan por favor y les explicare mas detalladamente ya que es parte de mi vida el procesamiento de imágenes en mi maestría.

Empezare con enseñarles como cambiar una imagen normal que tengamos por ahí y le cambiaremos a una escala de grises. Para entender como se hace ese cambio debemos sacar sus valores RGB de una imagen y manipularlos para cambiarlo a un tono gris; ya se que existen otras maneras de hacer los cambios por manipulación de funciones en android pero aquí quiero explicarles desde el punto de vista como dice mi asesor "caminando descalzo".

Existe una ecuación muy particular que usaremos:
Cita:
(0.299*r + 0.587*g + 0.114*b)
Las variables r, g y b son los valores de los canales correspondientes para la escala en Rojo, Verde y Azul; juntos crean la gama de colores que se conocen y por lo mismo si los manipulamos con dicha ecuación podremos sacar un resultado que sera como un promedio de los 3 canales. Pero!!! solo tenemos un resultados y 3 canales por llenar lo que hace falta es copiar ese resultados en los 3 canales y nuestra imagen quedara en una tonalidad gris.

Empecemos con el código de inicio (librerías cargadas):
Cita:
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
El main.xml quedaría de esta forma:
Cita:
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
android:id="@+id/tex"
/>
<ImageView
android:layout_width="wrap_content"
android:src="@drawable/icon"
android:id="@+id/Image"
android:layout_height="wrap_content"></ImageView>
<Button
android:text="GrayScale"
android:id="@+id/Butt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></Button>
Al inicio de nuestro activity podemos cargar las variables que vamos a usar yo las definí de la siguiente manera:
Cita:
Bitmap Imag; ImageView view; Button But; TextView text;
int picw, pich;
int pix[];
De donde:
Imag = Nuestra variable donde tendremos nuestra imagen cargada.
view = Donde cargaremos nuestra imagen modificada.
But = Nuestro boton.
text = Nuestro texto a desplegar.
picw = La variable donde cargaremos la dimensión de nuestra imagen en Width.
pich = La variable donde cargaremos la dimensión en Heigth.
pix[] = La variable donde estaremos guardando los valores de los pixeles.

Después de eso llenamos nuestras respectivas variables de la siguiente manera:
Cita:
Imag = BitmapFactory.decodeResource(getResources(), R.drawable.rgb);
picw = Imag.getWidth(); pich = Imag.getHeight();
view = (ImageView)findViewById(R.id.Image);
But = (Button)findViewById(R.id.Butt);
view.setImageBitmap(Imag);
text = (TextView)findViewById(R.id.tex);
pix = new int[picw*pich];
Después de tenerlas llenas con los valores a manipular crearemos un setOnClickListener a nuestro boton. Donde tendremos nuestra función GrayScale que cambiara nuestros valores de pix[] y desplegarlos en el view. Dentro del mismo evento también crearemos un nuevo Bitmap para no modificar nuestra imagen original solo por seguridad; de esta manera:
Cita:
Bitmap bm = Bitmap.createBitmap(picw, pich, Bitmap.Config.ARGB_4444);
Nuestra función que va a hacer el cambio a escala de grises lo declaramos del siguiente modo:
Cita:
public int[] GrayScale(Bitmap mBitmap)
{
int picw, pich;
picw = mBitmap.getWidth();
pich = mBitmap.getHeight();
int[] pix = new int[picw * pich];
mBitmap.getPixels(pix, 0, picw, 0, 0, picw, pich);
for (int y = 0; y < pich; y++)
for (int x = 0; x < picw; x++)
{
int index = y * picw + x;
int r = (pix[index] >> 16) & 0xff;
int g = (pix[index] >> 8) & 0xff;
int b = pix[index] & 0xff;
int R = (int)(0.299*r + 0.587*g + 0.114*b);
pix[index] = 0xff000000 | (R << 16) | (R << 8) | R;
}
return pix;
}

Aquí nuestra función recibe un Bitmap, sacamos sus valores de pixeles, leemos el RGB y aplicamos la ecuación que dijimos al inicio, guardamos de nuevo en la variable pix y cuando termine de leer todo lo que contiene pix lo regresamos.

De nuevo en nuestro evento del boton solo nos queda leer lo regresado y llenar nuestra nueva imagen con los pixeles modificados de la función.
Cita:
pix = GrayScale(Imag);
bm.setPixels(pix, 0, picw, 0, 0, picw, pich);
view.setImageBitmap(bm);
view.invalidate();
Y listooo!!! aquí esta la clásica imagen de muestra del resultado espero les sirva y comenten o mínimo dejen algo de puntos jeje.