Home   Artículos   Recursos   Foros   
Artíclos recientes publicados en Latindevelopers:

Visual C++: NSDoubleEdit: Un control para el manejo de números decimales en Visual C++.
Visual C++: Implementando una Calculadora en Visual C++
Visual C++: CCommandLine: Una clase para el uso de la linea de comando
Visual C++: Una clase para el manejo del Registro


Aplicar una máscara a una imagen

Aqui programadores en la plataforma Win32 con Visual C++ de Microsoft...

Moderador: latindeveloper

Aplicar una máscara a una imagen

Notapor kayss el Vie Nov 02, 2007 3:26 pm

Hola!

Alguno sabéis de una forma rápida de aplicar una máscara a una imagen en mapa de bits.

Yo primero creo la máscara (matriz nxn), recorro pixel a pixel la imagen, sitúo la máscara y recorro la máscara posición por posición para dicho pixel, y así con todos los demás pixels de la imagen.

Como os podeis imaginar esto tarda mucho en ejecutarse para una imagen de una resolución media.

Espero algunos sepais algún método más rápido


Saludos
kayss.
kayss
Novato
Novato
 
Mensajes: 9
Registrado: Mar May 30, 2006 1:03 am

Re: Aplicar una máscara a una imagen

Notapor ivancp el Vie Nov 02, 2007 4:41 pm

Puedes utilizar la funcion bitblt con el parametro SRC_AND, que realiza la operacion booleana AND con cada pixel.

Un ejemplo de emplear mascaras:
http://www.codeproject.com/bitmap/transbitmapmask.asp
ivancp
Programador Experimentado
Programador Experimentado
 
Mensajes: 344
Registrado: Jue Sep 06, 2007 12:57 pm

Notapor kayss el Vie Nov 09, 2007 2:01 pm

Hola,

Al final he conseguido reducir a la mitad el tiempo de procesamiento a la mitad con el siguiente código. Lo que hago es trabajar a nivel de byte, en lugar de a nivel de pixel, que es más rápido, aunque sigue tardando bastante. Espero que a vosotros se os ocurra otra idea o una mejora del código.

Código: Seleccionar todo
Bitmap^ AplicarMascara2(System::Drawing::Bitmap ^Imagen, cli::array<double>^ Mascara, Int32 Tamanio){
    this->ImagenFiltrada=gcnew System::Drawing::Bitmap (Imagen->Width, Imagen->Height);
    Int32 i, j, k, q, IncX, IncY, X, Y, ValorPixel, PosVectorRGB, Sumatorio;
    Color color;
    Int32 Cte1=Tamanio/2;

    // formato de pixel
    PixelFormat pxf = PixelFormat::Format24bppRgb;

    // Bloqueamos los pixels de la imagen original y la filtrada
    Rectangle rect = System::Drawing::Rectangle(0, 0, Imagen->Width, Imagen->Height);
    BitmapData ^bmpDatosOriginal = Imagen->LockBits(rect, ImageLockMode::ReadWrite, pxf);
    BitmapData ^bmpDatosFiltrada = ImagenFiltrada->LockBits(rect, ImageLockMode::ReadWrite, pxf);

    // Obtenemos la direcciones de comienzo
    IntPtr ptrOriginal = bmpDatosOriginal->Scan0;
    IntPtr ptrFiltrada = bmpDatosFiltrada->Scan0;

    // Declaramos los arrays para almacenar los bytes de los bitmaps
    Int32 numBytes = Imagen->Width * Imagen->Height * 3;
    array<Byte> ^valoresRGBOriginal = gcnew array<Byte>(numBytes);
    array<Byte> ^valoresRGBFiltrada = gcnew array<Byte>(numBytes);

    // Copiamos los valores RGB a los arrays
    Marshal::Copy(ptrOriginal, valoresRGBOriginal, 0, numBytes);
    Marshal::Copy(ptrFiltrada, valoresRGBFiltrada, 0, numBytes);

    // Recorremos la imagen
    for(i=0; i<Imagen->Width; i++){
        for (j=0; j<Imagen->Height; j++){
           
            IncY=Cte1;
            Sumatorio=0;

            // Recorremos la máscara
            for (k=0; k<Tamanio; k++){
               
                Y=j+IncY;
                IncX=Cte1;

                for (q=0; q<Tamanio; q++){
                    X=i+IncX;
                    if ((X>=0&&X<Imagen->Width) && (Y>=0&&Y<Imagen->Height)) Sumatorio=Sumatorio + (Int32)(Mascara[(Cte1+IncX)*3 + (Cte1+IncY)])*(valoresRGBOriginal[(Y*Imagen->Width+X)*3]);

                    IncX--;
                }
                IncY--;
            }
           
            // El valor del pixel será el valor del sumatorio obtenido
            if (Sumatorio>0)ValorPixel=Sumatorio%255;
            else ValorPixel=0;
            PosVectorRGB=(j*Imagen->Width+i)*3;
            valoresRGBFiltrada[PosVectorRGB]=ValorPixel;
            valoresRGBFiltrada[PosVectorRGB+1]=ValorPixel;
            valoresRGBFiltrada[PosVectorRGB+2]=ValorPixel;
        }
    }

    // Copiamos de nuevo los valores del array al bitmap
    Marshal::Copy(valoresRGBFiltrada, 0, ptrFiltrada, numBytes);

    // Desbloqueamos los bites
    ImagenFiltrada->UnlockBits(bmpDatosFiltrada);
    Imagen->UnlockBits(bmpDatosOriginal);

    return ImagenFiltrada;

}



Un saludo
kayss.
kayss
Novato
Novato
 
Mensajes: 9
Registrado: Mar May 30, 2006 1:03 am


Volver a Visual C++

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados