Bienvenidos

En este blog se publicaran proyectos en c++, les doy la bienvenida y espero sea de ayuda para ustedes este espacio, no olviden comentar!

domingo, 11 de septiembre de 2011

Manipulacion de pixeles en borland c++.

Descripción:  En este post vamos a realizar un programa para manejar los pixeles de un imagen .bmp ademas de manipular colores.
El objetivo de este post es proporcionar una clara explicación del manejo de Borland C++ Builder 6 para graficos.

Comencemos
1. Nuestra interfaz debe quedar de la siguiente manera:
   
  2.Primero agregamos 3 Images y 3 Button
  
Para agregar los componentes nos vamos a la barra que se encuentra arriba y seleccionamos lo que necesitamos.



En el caso de las imagenes podemos darle el tamaño que deseamos pero teniendo en cuenta que vamos a insertar una imagen del mismo tamaño. Yo lo puse 201x281 PIXELES para una imagen de la película UP. 
Para modificar el tamaño te vas a Properties(PROPIEDADES) en la parte izquierda del compilador.




Para la imagen 2 y 3 ponemos una sobre la otra pero en el caso de la Image3 le damos un tamaño contario 281x201 como lo vemos en la imagen.

Ahora vamos agregar el resto de los componentes necesarios.
1 GroupBox y 4 RadioButton sobre el GroupBox.

Ahora solo faltan 2 botones(Button)extras y un SpeedButton.



3.Vamos a darles Texto a nuestros componentes.


En el caso de nuestros Buttons y GroupBox nos vamos a propiedades y cambiamos la propiedad Caption por los nombres correspondientes como se ve en la figura anterior. 
Button1-Rojo
Button2-Verde
Button3-Azul
Button4-Reflejo
Button5-Invertir
RadioButto1-Verde
RadioButto2-Azul
RadioButto3-Rojo
RadioButto1-Ningu Color
GoupBox1-Tono del Reflejo

Para el SpeedButton vamos a agregarle un icono y a poner en su propiedad Caption el Texto "Rotar".
Para crear nuestro icono nos vamos a la barra de menús y seleccionamos la pestaña Tools y seleccionamos Image Editor.



Y procedemos a crear un icono que represente el símbolo de ROTACIÓN.
Para iniciar damos clic en Archivo/Nuevo/ y le damos el la opción BitMap file
 Eliges el tamaño ejem(20x20) y creamos nuestro icono como lo deseemos. Yo dibuje la flecha con la herramienta lápiz y le di un fondo gris.
Guarda la imagen!
Ahora seleccionamos el SpeedButton cambiamos el Caption  y nos vanos a la propiedad Glyph. Le damos clic al boton señalado en la segunada imagen.

Nos aparecerá una ventana y le damos clic en load, buscamos nuestra imagen BMP previamente creada y le damos clic en OK
Haremos algo similar para el componete Image1, solo que ahora podremos poner la imagen que a nosotros nos agrade. La propiedad es Picture:
La forma nos queda de la siguiente manera:

3. El siguiente paso es programar los botones para que realicen las siguientes funciones:
Los botones con el texto "Rojo","Verde","Azul" darán la tonalidad de dicho color a nuestra imagen.
Le damos doble clic al boton con el texto "Rojo" y agregamos el siguiente código:

Botón "Rojo"

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 Image2->Visible=true;//Ponemos la imagen 2 visible en la forma.
 TColor color;//Creamos una variable del tipo TColor para almacenar el pixel actual
 for(int x=0;x<Image1->Width;x++)
   for(int y=0;y<Image1->Height; y++)
     {//Ciclo para recorrer el arreglo de la imagen, recordemos que el .bmp es
      //una matriz, empezamos de la posición (0,0) hasta (Whidth, Heigth)

       color= Image1->Canvas->Pixels[x][y];
       //Aquí almacenamos el pixel según la posición usando la clase Canvas                                                         
       Image2->Canvas->Pixels[x][y]=color&255;
       // por ultimo a la imagen 2 le almacenamos el valor actual de color y le damos una tonalidad //roja
     }

}
//----------------------------------------------------------------------------

Hacemos lo mismo para los botones "Verde" y "Azul" teniedo en cuenta lo siguiente
0X,00,00,00=Transparencia, Azul, Verde, Rojo.
activa rojo=OX0000FF recordemos que FF es igual a 255

activa verde=OX00FF00 en este caso activamos el verde pero el nivel de bits no es el mismo que el rojo
hacemos un corrimiento a la izquierda de 8 bits (255<<8)
activa azul=OXFF0000 es similar solo que hacemos un corrimiento de 16 bits(255<<16)

Para el Botón "Verde" 

//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
    Image2->Visible=true;
   TColor color;
 for(int x=0;x<Image1->Width;x++)
   for(int y=0;y<Image1->Height; y++)
     {
       color= Image1->Canvas->Pixels[x][y];
       Image2->Canvas->Pixels[x][y]=color&(255<<8);//Tonalidad verde
     }
}
//---------------------------------------------------------------------------

Para el Botón "Azul"


void __fastcall TForm1::Button3Click(TObject *Sender)
{
     Image2->Visible=true;
     TColor color;
 for(int x=0;x<Image1->Width;x++)
   for(int y=0;y<Image1->Height; y++)
     {
       color= Image1->Canvas->Pixels[x][y];
       Image2->Canvas->Pixels[x][y]=color&(255<<16);//Tonalidad azul
     }
}
//---------------------------------------------------------------------------

Veamos como se ve al correr el programa y dar clic al botón programado






Ahora vamos a programar el botón de "Reflejo"
Para este botón he agregado opciones con RadioButtons para seleccionar un color haciéndolo mas dinámico.


void __fastcall TForm1::Button5Click(TObject *Sender)
{


   TColor color;//variable para almacenar el pixel
   Image3->Visible=false;//pone a la imagen 3 invisible
   Image2->Visible=true;//pone la imagen dos visible

   for(int x=0, r=Image1->Width ;x < Image1->Width ;x++, r--)
      for(int y=0; y < Image1->Height; y++)
       {//El reflejo es muy simple, consiste en enviar el pixel de la imagen 1 de la pos(0,0) a
         //la pos(width, 0) de la imagen 2, (0,1)->(width,1) así sucesivamente y cuando
         // termine el eje decrementamos width, es decir el eje x, hacemos un recorrido invertido

      //El RadioButton4 sirve para no tener seleccionada ninguna opción
         color= Image1->Canvas->Pixels[x][y];
         Image2->Canvas->Pixels[r][y]=color;//recorrido invertido

       if(RadioButton1->Checked)//si esta seleccionado RadioButton3
        {
          color= Image1->Canvas->Pixels[x][y];
          Image2->Canvas->Pixels[r][y]=color&(255<<8);//verde
 
        }
       if(RadioButton2->Checked)//si esta seleccionado RadioButton3
        {
          color= Image1->Canvas->Pixels[x][y];
          Image2->Canvas->Pixels[r][y]=color&(255<<16);//Azul
       
        }
       if(RadioButton3->Checked)//si esta seleccionado RadioButton3
        {
          color= Image1->Canvas->Pixels[x][y];
          Image2->Canvas->Pixels[r][y]=color & 255;//rojo

        }
     }
}
//---------------------------------------------------------------------------

Visualización



Botón "Rotar"

Ahora el botón de rotar, aquí vamos a hacer uso de la Image3 tercera imagen agregamos el siguiente código
al botón.
Primero creamos 4 variables del tipo bool para intercalar entre las opciones siguientes
//----------------------------------------------------------------------------------------
bool band1=true; //bandera 1-> Girar hacia la derecha
bool band2=false; //bandera 2-> Invertir
bool band3=false; //bandera 3-> Girar hacia la izquierda
bool band4=false; //bandera 4-> Imagen normal



void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
  TColor color;

  if(band1==true)
  {
    Image3->Visible=true;//dejamos que se muestre la imagen tres
    Image2->Visible=false;//quitamos la imagen 2 para evitar empalmes de imágenes

    for(int x=0, y1=Image1->Width; x<Image1->Width; x++,y1--)
      for(int y=0, x1=0;y<Image1->Height; y++,x1++)
       {//este ciclo y su contenido sirve para girar la imagen hacia la derecha
         color= Image1->Canvas->Pixels[x][y];
         Image3->Canvas->Pixels[x1][y1]=color;
       }
         band1=false;//deshabilitamos
         band2=true;//habilitamos la siguiente bandera para invertir
         band3=false;
         band4=false;
  }
  else
  {
      if(band2==true)//entra al estar habilitada band2
          {
          Image3->Visible=false;//hacemos invisible la imagen 3
          Image2->Visible=true;//dejamos la 2 para mostrar la inversión

            for(int x=0; x<Image1->Width; x++)
              for(int y=0, c=Image1->Height-1;y<Image1->Height; y++,c--)
                 {//método de inversión
                    color= Image1->Canvas->Pixels[x][y];
                    Image2->Canvas->Pixels[x][c]=color;
                 }

         band1=false;
         band2=false;;//deshabilitamos
         band3=true;//habilitamos la tercer bandera band3
         band4=false;
          }
          else
            {
             if(band3==true)
               {
                  Image3->Visible=true;//cambiamos a habilitar
                  Image2->Visible=false;// la ponemos invisible

                  for(int x=0,y1=0; x<Image1->Width; x++,y1++)
                    for(int y=0,x1=Image3->Width;y<Image1->Height; y++,x1--)
                      {// método de girado a la izquierda, lo contrario al girado a la derecha
                        color= Image1->Canvas->Pixels[x][y];
                        Image3->Canvas->Pixels[x1][y1]=color;
                      }

                 band1=false;
                 band2=false;
                 band3=false;;//deshabilitamos
                 band4=true;//habilitamos band4

               }
               else
               {
                  if(band4==true)
                   {
                      Image3->Visible=false;//dejamos invisible la imagen 3
                      Image2->Visible=true;//mostramos la imagen 2

                     for(int x=0; x<Image1->Width; x++)
                        for(int y=0;y<Image1->Height; y++)
                          {//solo copiamos la imagen tal cual
                             color= Image1->Canvas->Pixels[x][y];
                             Image2->Canvas->Pixels[x][y]=color;
                          }

                        band1=true;//volvemos a habilitar la bandera 1 para que regrese y haga lo mismo cada vez
                                          //que lo deseemos  
                        band2=false;
                        band3=false;
                        band4=false;;//deshabilitamos
                   }
               }
            }
  }
}
//---------------------------------------------------------------------------------------


Visualización




Bueno aqui finaliza nuestro programa.

Espero que les sea de ayuda y por favor dejen un comentario y dejen sus quejas y sugerencias.
Tomen en cuenta que es mi primer post.
Muchas gracias!