Colabora
 

BuscaColor

[Obtener el color de cualquier pixel en el escritorio]

 

Fecha: 15/Nov/2008 (14-11-08)
Autor: Joaquin Medina Serrano joaquin@medina.name
Web: http://joaquin.medina.name/

 


Introducción

Este artículo describe y comenta la herramienta ‘BuscaColor’ que puede usarse para obtener el color de cualquier pixel del escritorio

pantalla (9K)


Introducción

Cuando se trabaja con páginas Web o gráficos, es frecuente necesitar una herramienta que obtenga el valor del color de una región particular de otra aplicación Windows. Por ejemplo necesitamos obtener el color de una imagen para usarlo como color de fondo de una página web en la que se mostrara la imagen.

En realidad, el problema tiene una solución muy simple, existen en internet multitud de herramientas freeware que realizan esta tarea a la perfección, solo tienes que escribir la palabra "colorfinder" en un buscador para obtener un montón de resultados. Lo que ocurre es que hace tiempo que quería escribir una de estas herramientas, así que cuando se me presento el problema decidí ponerme manos a la obra.

Lo primero que hice fue mirar cómo han resuelto el problema otros programadores, y centrándonos en el caso de Visual Basic, todos los códigos que he mirado hacían uso de la API de Windows. En mi caso particular, y ya que me ponía a ello, quería escribirlo usando código estándar de .NET, es decir nada de llamadas a funciones API, y el resultado de esa pequeña investigación es el código que muestra este articulo.


Como se usa esta herramienta

pantalla (9K)

Para obtener el valor del color de un pixel del escritorio, se pulsa con el botón izquierdo del ratón la imagen [Imagen que hay que pulsar]. En ese momento, el cursor del ratón cambia a una cruz [+]. Manteniendo pulsado el botón izquierdo del ratón, desplazaremos el cursor hasta el lugar del escritorio donde queremos obtener el color, y entonces soltaremos el botón izquierdo del ratón. En este momento, la herramienta obtendrá el color del pixel y mostrara el resultado en los cuadro de texto.

Mientras se desplaza el ratón, se obtiene el color de los pixeles por los que se va desplazando, el código no funciona muy fino y el proceso de mostrar el color parece que va a saltos, pero cuando se detiene el movimiento del ratón, el color se muestra sin problemas


Mirando un poco el código

He escrito esta herramienta en forma de Control, porque me parece que así tiene más versatilidad. A continuación puedes ver la imagen que presenta el control que realiza el trabajo de calcular el color del pixel

imagen del Control BuscaColor (2 Kb)

A la hora de mirar el código hay tres partes muy diferenciadas: a)la interface de usuario, b)el control del movimiento del ratón y c)el proceso de obtención del color.


a) La interface de usuario

La interface de usuario dispone de las siguientes propiedades:

  • Propiedad ZColor as cColor, de solo lectura y que devuelve el color obtenido por el control
  • Propiedad ZCoordenadasCaptura() As Point, de solo lectura. Devuelve el punto de la pantalla donde se captura el color
  • Propiedad ZColorHtml() As String de solo lectura. Devuelve el color en formato HTML [p.e. #FFAABB]

Nota:
La letra "Z" de [ZColor], [ZCoordenadasCaptura], y [ZColorHtml] es una ¿mala? costumbre que tengo a la hora de escribir controles, y su razón está en que de esta forma todos las propiedades y funciones escritas por mi salen al final en la ayuda en línea.


b) Proceso de obtención del color

El proceso de obtención del color es un poco más complicado, y costa de varias fases:

En primer lugar se definen las variables internas del control que vamos a necesitar.

  '-----------------------------------------------------------------------
  'Variables de la clase
  '-----------------------------------------------------------------------
  'Imagen para averiguar el color del Pixel, no se muestra
  'Creamos una imagen con tamaño 1*1 para averiguarl el color
  <NonSerializedAttribute()> _
  Private _btmp As Bitmap

  'Creamos el objeto [Graphics] a partir de la imagen
  <NonSerializedAttribute()> _
  Private _grfx As Graphics

  ' posicion del cursor
  <NonSerializedAttribute()> _
   Private _posicionCursor As Point

  ' Color Obtenido
  Private _colorCalculado As System.Drawing.Color = Color.White

A continuación una función que las inicialice

 '-----------------------------------------------------------------------
 ' Inicializar los valores de las variables que intervienen en la captura del color
 Private Sub InicioBuscarColor()
     'Imagen para averiguar el color del Pixel, no se muestra
     'Creamos una imagen con tamaño 1*1 para averiguarl el color
     _btmp = New Bitmap(1, 1)

     'Creamos el objeto [Graphics] a partir de la imagen
     _grfx = Graphics.FromImage(_btmp)

 End Sub
 

Y otra que las destruya.

En la ayuda MSDN se especifica que cuando ya no necesitemos la clase [graphics], debemos llamar explícitamente a su método [dispose]

'-----------------------------------------------------------------------
' Finalizar las variables que intervienen en la captura del color
Private Sub FinBuscarColor()
    ' La libreria MSDN indica que se debe llamar explictamente al 
    ' metodo [Dispose] de [Graphics] cuando no se necesite mas
    If Not _btmp Is Nothing Then
        ' Comprobar si se puede llamar al dipose del objeto
        If TypeOf _btmp Is IDisposable Then
            _btmp.Dispose()
        End If
        ' objeto a null
        _btmp = Nothing
    End If

    If Not _grfx Is Nothing Then
        ' Comprobar si se puede llamar al dipose del objeto
        If TypeOf _grfx Is IDisposable Then
            _grfx.Dispose()
        End If
        ' objeto a null
        _grfx = Nothing
    End If
End Sub

Y el código que obtiene el color del pixel sobre el que está el ratón

'-----------------------------------------------------------------------
' Proceso de obtencion del color del pixel sobre el que esta el cursor
Private Function GetColorPixel() As Drawing.Color
    'Obtenemos la posición del cursor  y almacenarlo en la variable de clase
    _posicionCursor = Cursor.Position

    ' copiar el rectangulo donde esta el cursor en el bitmap
    ' en el bitmap de un pixel que hemos creado
    _grfx.CopyFromScreen(_posicionCursor, New Point(0, 0), _btmp.Size)

    ' Obtener el color del pixel y almacenarlo en la variable de clase
    _colorCalculado = _btmp.GetPixel(0, 0)

    '  Disparar el evento ColorCapturado
    Call DispararEventoColorCapturado()

    ' Devolver valor del color
    Return _colorCalculado
End Function

c) El movimiento del ratón

Por otra parte, el movimiento del ratón también tiene su pequeña enjundia.

En primer lugar cuando pulsamos el botón izquierdo del ratón encima del botón [Imagen que hay que pulsar]

  • Borrar la imagen y cambiar el cursor del ratón a una cruz
  • Iniciar el proceso de búsqueda del color instanciando las variables
  '-----------------------------------------------------------------------
  Private Sub ButtonArrastraRaton_MouseDown( _
          ByVal sender As Object, _
          ByVal e As System.Windows.Forms.MouseEventArgs) _
          Handles ButtonArrastraRaton.MouseDown

      ' borrar la imagen
      ButtonArrastraRaton.Image = Nothing
      ' poner el cursor con una cruz
      Cursor.Current = Cursors.Cross
      ' inicio del proceso de buscar color (Instanciar variables)
      Call InicioBuscarColor()
  End Sub

A continuación lo que ocurre cuando desplazamos el ratón

  • Obtener el color de los puntos por los que se va desplazando el ratón
  '-----------------------------------------------------------------------
  Private Sub ButtonArrastraRaton_MouseMove( _
          ByVal sender As Object, _
          ByVal e As System.Windows.Forms.MouseEventArgs) _
          Handles ButtonArrastraRaton.MouseMove

      ' solo funciona si esta pulsado el boton derecho del raton
      If e.Button = Windows.Forms.MouseButtons.Left Then
          ' poner el color 
          Me.ButtonArrastraRaton.BackColor = GetColorPixel()
      End If
  End Sub

Y por ultimo lo que ocurre cuando soltamos el botón izquierdo, es decir cuando decidimos que ese es el punto del escritorio del que queremos saber el color

  • Recuperar el cursor por defecto del ratón
  • Mostrar la imagen inicial
  • Obtener el color del punto donde está el ratón
  • Destruir las variables empleadas en la búsqueda del color
'-----------------------------------------------------------------------
Private Sub ButtonArrastraRaton_MouseUp( _
        ByVal sender As Object, _
        ByVal e As System.Windows.Forms.MouseEventArgs) _
        Handles ButtonArrastraRaton.MouseUp

    ' restaurar la imagen del boton
    ButtonArrastraRaton.Image = My.Resources.ColorHS
    ' restaurar el cursor por defecto
    Cursor.Current = Cursors.Default
    '--------------------------------------------
    ' Almacenar el color obtenido
    Me.ButtonArrastraRaton.BackColor = GetColorPixel()
    ' finalizar el proceso de buscar color
    Call FinBuscarColor()
End Sub

Puntos de interés

  • El proceso de captura del color esta en el control [UCBuscaColor.vb]
  • Cuando se captura un color, el control dispara el evento [ZColorCapturado]
  • La herramienta utiliza el control para capturar el color y trabajar con el

Historial

V.2008.11.5.1 es la versión inicial


Licencia

Copyright (C) 2008 Joaquín Medina Serrano.

Este código es de mi propiedad sin que exista, ni ahora, ni en el futuro, ningún género de dudas. No es un código libre, esta sujeto a las siguientes limitaciones:

  1. A pesar de las ¿Exhaustivas? , ¿Intensas?, y ¿cuidadosas? (ha, ha, ha...) pruebas a que he sometido este código, el principio de Murphy siempre está trabajando y si algo puede ir mal seguro que va mal. Por esa razón, este código se proporciona *Como esta* sin ninguna garantía de ninguna clase
  2. La idea de escribirlo es la de ganar dinero con él. Si usando este código, ganas dinero, yo quiero mi parte. En caso contrario, puedes usarlo como creas conveniente, pero debes cumplir las siguientes condiciones:
    • a) Debes indicar claramente el autor (o sea mi nombre) y el sitio Web de donde se lo has copiado (o sea mi web)
    • b) Debes invitar a una cerveza a su creador, (o sea a mi), si no me localizas, me conformo con que me envíes un *Emilio* contándome para que lo has empleado.
    • c) Si haces algo interesante con el, me gustaría verlo

Sobre el autor

Autobombo del autor
  • Joaquín Medina Serrano [Web]
  • Autor de libros sobre Visual Basic, Cobol y Office
  • He impartido de cursos sobre programación en Lenguaje C, Visual Basic 6, Visual Basic .NET y Fundamentos de Programación
  • He desarrollado diversas aplicaciones de gestión, utilizando herramientas como Clipper, Visual Basic 6 y Visual Basic .NET.
  • Autor de artículos sobre Programación Orientada a Objetos, y Visual Basic .NET
  • El último curso de capacitación realizado ha sido el Máster en Servicios Web, Seguridad Informática y Aplicaciones de Comercio Electrónico de la [Universidad de Zaragoza ]


Compromiso del autor del artículo con el sitio del Guille:

Lo comentado en este artículo está probado (y funciona) con la siguiente configuración:

El autor se compromete personalmente de que lo expuesto en este artículo es cierto y lo ha comprobado usando la configuración indicada anteriormente.

En cualquier caso, el Guille no se responsabiliza del contenido de este artículo.

Si encuentras alguna errata o fallo en algún link (enlace), por favor comunícalo usando este link:

Gracias.


Código de ejemplo (comprimido):

 

Fichero con una demo del programa: jms32_DemoBuscaColor.zip - 66.00 KB

(MD5 checksum: ACC680FEDDC29CE4B574083AEF82561A)

Fichero con el código Fuente: jms32_SolucionDllColorFuentes.zip - 185.00 KB

(MD5 checksum: F3E14A2DBAE09505EE39DB34B671213E)

 


Ir al índice principal de el Guille