Color de Bit

Post Reply
antolin
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Color de Bit

Post by antolin »

Hola Foreros, aqui os dejo unas pequñas utilidades en C++ que a lo mejor le viene bien a alguién. A mi me han solucionado un pequeño 'comportamiento' que venía disgustandome desde hace muchos años.

Code: Select all | Expand

HB_FUNC( GETBMPPIXEL )  // GetBmpPixel( hBitmap,nY,nX )
   {
   HBITMAP hBmp = ( HBITMAP ) hb_parnl( 1 ) ;
   BITMAP  bmp ;

   int nY = hb_parni( 2 )// nTop
   int nX = hb_parni( 3 )// nLeft

   GetObject( ( HBITMAP ) hBmp, sizeof( BITMAP ), ( LPSTR ) &bmp ) ;

   if ( bmp.bmBits == 0 || bmp.bmBitsPixel < 24 )
      {
      hb_retnl( ( LONG ) 0 ) ;
      }
   else
      {
      BYTE * lpDib = ( BYTE * ) bmp.bmBits ;

      if ( bmp.bmBitsPixel == 24 )
     {
     nY = (bmp.bmHeight-1-nY) * ( ( ( ( ( bmp.bmWidth*3 ) - 1 ) / 4 ) + 1 ) * 4 ) ;
     nX = (nX*3)+nY ;
     }
      else  // bmp.bmBitsPixel == 32
     {
     nY = (bmp.bmHeight-1-nY) * ( bmp.bmWidth * 4 ) ;
     nX = (nX*4)+nY ;
     }

      hb_retnl( ( LONG ) ( lpDib[nX+2] + (lpDib[nX+1] << 8) + (lpDib[nX+0] << 16) ) ) ;
      }
   }


HB_FUNC( GETBMPALPHA )  // GetBmpAlpha( hBitmap,nY,nX )
   {
   HBITMAP hBmp = ( HBITMAP ) hb_parnl( 1 ) ;
   BITMAP  bmp ;

   int nY = hb_parni( 2 )// nTop
   int nX = hb_parni( 3 )// nLeft

   GetObject( ( HBITMAP ) hBmp, sizeof( BITMAP ), ( LPSTR ) &bmp ) ;

   if ( bmp.bmBitsPixel == 32 )
      {
      BYTE * lpDib = ( BYTE * ) bmp.bmBits ;

      nY = (bmp.bmHeight-1-nY) * ( bmp.bmWidth * 4 ) ;
      nX = (nX*4)+nY ;

      hb_retnl( ( LONG ) lpDib[nX+3] ) ;  
      }

   else hb_retnl( ( LONG ) 0 ) ;
   }

La primera función nos dice de qué color es el pixel (nX,nY) del bitmap 'hBitmap'. La segunda, qué nivel de opacidad/transparencia tiene ese pixel en el canal alpha. La primera utilidad es parecida a GetPixel(), pero muuucho más rápido, cientos de veces más rápido, la segunda no tiene equivalencia. La diferencia es que trabajan con bitmaps (o DIB's) de 24 o 32 bits de profundidad de color. Ventaja? bueno en mi aplicación "Selector de color":

viewtopic.php?f=6&t=30195

Intenté capturar los colores con GetPixel() y fue totalmente imposible, demasiado lento, el programa se atrancaba y no progresaba, con GetBmpPixel() el resultado es inmediato.

La pega que no conseguía resolver desde hace años es la siguiente: Me gusta dibujar botones, de hecho he modificado la clase TBITMAP para utilizarla como un botón sensible al ratón, es decir que cuando el cursor pasa por encima del control pasa de CursorArrow() a CursorHand() y cambio el bitmap, cuando dejo de estar sobre el control, el cursor vuelve a CursorArrow() y recupero el bitmap original. Hasta aquí ningún misterio. Lo malo es cuando el bitmap que utilizo como botón no es rectángular, por ejemplo un círculo, un libro, un coche etc, entonces mejor será que lo explique con un gráfico:

Image

Imagen 1º: El cursor aun no ha llegado al botón representado por una circunferencia de colores, y tiene forma CursorArrow().

Imagen 2º: El cursor está sobre el control TBITMAP, y el cursor pasa a CursorHand(), pero aún está sobre la parte transparente del botón. Al cambiar ahí, es como si pasara a CursorHand() antes de llegar al botón. Al abandonar el control ocurre el efecto contrario, el cursor continúa como CursorHand() cuando ya no está sobre el dibujo, porque sigue estando sobre la parte transparente y aún no ha salido del control. Ese el efecto desagradable que qería suprimir con mi función.

Imagen 3º: El cursor está sobre el control pero sigue como CursorArrow() porque con GetBmpPixel() detecto que el pixel es de color transparente.

Imagen 4º: El cursor se encuentra sobre la parte opaca del botón y cambia a CursorHand(), se mantendrá así mientras detecte que no está sobre color transparente.

En mi clase modificada, también puedo representar bitmaps de 32 bits con canal de transparencia. Gracias a GetBmpAlpha() puedo saber si el cursor está sobre una parte transparente o traslucida, por ejemplo una sombra, o sobre una parte más opaca. Por ejemplo puedo ordenar que cambie a CursorHand() solo cunado el nivel de opacidad sea mayor de 200.

Por último, precisar que estás funciones solo trabajan con mapas de bits (o DIB's) de 24 o 32 bits de profundidad de color. Con bitmaps de 8 bits, 256 colores o monocromos, no lo he investigado. Y con lo poco que he visto, ahora mismo sería incapaz de implementarlo. Si a alguien le interesa y sabe hacerlo, si no le importa, estaría bien que lo expusiera en este post.

Espero que os sea de utilidad.

Un saludo.
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
User avatar
Antonio Linares
Site Admin
Posts: 42520
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 31 times
Been thanked: 75 times
Contact:

Re: Color de Bit

Post by Antonio Linares »

Gracias por compartir :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
cuatecatl82
Posts: 625
Joined: Wed Mar 14, 2007 6:49 pm
Location: San Cristobal de las Casas, Chiapas México
Contact:

Re: Color de Bit

Post by cuatecatl82 »

Antolin:

Podrias regalarnos un ejemplo de como usar estas funciones, necesito hacer un ColorPick y encontre estas funciones, lo he compilado y agregado a mi proyecto pero no genera error, solo muestra un mensaje de error:

Image

Saludos y gracias..
Soluciones y Diseño de Software
Damos Soluciones...

I.S.C. Victor Daniel Cuatecatl Leon
Director y Diseñador de Proyectos

http://www.soldisoft.unlugar.com
http://www.sisa.unlugar.com
danyleon82@hotmail.com
www.facebook.com/victordaniel.cuatecatlleon
antolin
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Re: Color de Bit

Post by antolin »

A lo largo de este post

viewtopic.php?f=6&t=30975

He colcado un enlace a mi clase MRFButon donde utilizo esas funciones y explico como lo uso.

En cuanto al error que te da, no se a que se debe ni lo que significa. Lo mismo te falta alguna cabecera.

Saludos
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
antolin
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Re: Color de Bit

Post by antolin »

Utilizo esta cabeceras:

fwharb.h
hbapi.h
clipapi.h
winten.h
windows.h
mmsystem.h
winuser.h
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
User avatar
cuatecatl82
Posts: 625
Joined: Wed Mar 14, 2007 6:49 pm
Location: San Cristobal de las Casas, Chiapas México
Contact:

Re: Color de Bit

Post by cuatecatl82 »

Gracias Antolin:

Pero Definitivamente no pude compilar el archivo en C. Gracias de todas maneras..
Soluciones y Diseño de Software
Damos Soluciones...

I.S.C. Victor Daniel Cuatecatl Leon
Director y Diseñador de Proyectos

http://www.soldisoft.unlugar.com
http://www.sisa.unlugar.com
danyleon82@hotmail.com
www.facebook.com/victordaniel.cuatecatlleon
antolin
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Re: Color de Bit

Post by antolin »

Vaya. Los siento. Algo debe fallar en tu compilación. Pues he estado mirando y yo tampoco tengo DBENG.DLL en mi Borland C++ 5.5. De todas formas, mira en el directorio:

Code: Select all | Expand

c:\BCC55\Lib\PSDK\

De todas formas, por si te sirve de ayuda, en mi BCC32.CFG tengo:

Code: Select all | Expand

-IC:\Borland\BCC55\include
-IC:\XHARBOUR\include
-IC:\FWH\include
-LC:\Borland\BCC55\lib
-LC:\XHARBOUR\lib
-LC:\FWH\lib

Y en mi ILINK32.CFG tengo:

Code: Select all | Expand

-LC:\Borland\BCC55\lib

Para la compilación utilizo Bcc32 con los parametros

Code: Select all | Expand

Bcc32.exe -c -X -O2 c:\Bcc55\func32\Fichero.C
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
Post Reply