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:
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.(0.299*r + 0.587*g + 0.114*b)
Empecemos con el código de inicio (librerías cargadas):
Cita:
El main.xml quedaría de esta forma: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;
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;
Cita:
Al inicio de nuestro activity podemos cargar las variables que vamos a usar yo las definí de la siguiente manera:<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>
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>
Cita:
De donde:Bitmap Imag; ImageView view; Button But; TextView text;
int picw, pich;
int pix[];
int picw, pich;
int pix[];
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:
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: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];
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];
Cita:
Nuestra función que va a hacer el cambio a escala de grises lo declaramos del siguiente modo:Bitmap bm = Bitmap.createBitmap(picw, pich, Bitmap.Config.ARGB_4444);
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;
}
{
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:
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.pix = GrayScale(Imag);
bm.setPixels(pix, 0, picw, 0, 0, picw, pich);
view.setImageBitmap(bm);
view.invalidate();
bm.setPixels(pix, 0, picw, 0, 0, picw, pich);
view.setImageBitmap(bm);
view.invalidate();