VB6 – Leer un Pixel de una Imagen

A muchos de nos interesa poder acceder hasta los pixeles de una imagen.

En esta entrada rápida veremos una forma de como acceder al interior de una imagen para así obtener el color de cada uno de los pixeles que la forman.

Después del éxito de la entrada anterior, que trataba de como manejar una imagen con visual basic 6 y despues de un pequeño dialogo sobre ella, he acabado haciendo un pequeña aplicacion en la que muestro como leer cada pixel de una imagen.

Parto de un formulario diseñado rápidamente, en el que he añadido:

Un CommandButton, en el que ejecutare el código.
Un PictureBox, en el que cargare la imagen a leer.
Y un ListBox, en el que listare el color de cada uno de los pixeles de la imagen.

Lamentablemente (o no…) no utilizaer la libreria ImageMagick®, sino simplemente una API de Windows.

Por tanto necesito declara la funcion de la API:

Public Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, _
ByVal y As Long) As Long

Y este es el código de lectura de los pixeles, muy sencillo ¿verdad?.

Option Explicit

Private Sub cmdComando_01_Click()
'
'--------------------------------------------'
' CON ESTE BOTON CARGAMOS Y LEEMOS LA IMAGEN
'--------------------------------------------'
'
'--------------------------------------------'
' CARGO LA IMAGEN
With Picture1
   .AutoSize = True ' QUIERO TENER LA IMAGEN A TAMAÑO REAL
   .ScaleMode = vbPixels
   .Picture = Nothing
   .Picture = LoadPicture(App.Path & "\Imagen_Lectura.bmp")
   .Refresh
End With
'--------------------------------------------'
' LEO PIXEL A PIXEL (EL COLOR)
List1.Clear
'
Dim lonL_Cont_X_01 As Long
Dim lonL_Cont_Y_01 As Long
Dim lonL_Anchura_Imagen_X_01 As Long
Dim lonL_Altura_Imagen_Y_01 As Long
Dim lonL_Color_Pixel_01 As Long
Dim lonL_Color_R_01 As Long
Dim lonL_Color_B_01 As Long
Dim lonL_Color_G_01 As Long
'
lonL_Anchura_Imagen_X_01 = Picture1.ScaleWidth
lonL_Altura_Imagen_Y_01 = Picture1.ScaleHeight
'
For lonL_Cont_Y_01 = 1 To lonL_Altura_Imagen_Y_01 - 1
   For lonL_Cont_X_01 = 1 To lonL_Anchura_Imagen_X_01 - 1
      ' AQUI ESTA EL TRUCO!!! LA FUNCION GetPixel
      lonL_Color_Pixel_01 = GetPixel(Picture1.hdc, lonL_Cont_X_01, lonL_Cont_Y_01)
      '
      ' SACAR LA DESCOMPOSICION RGB
      lonL_Color_R_01 = lonL_Color_Pixel_01 Mod 256
      lonL_Color_B_01 = Int(lonL_Color_Pixel_01 / 65536)
      lonL_Color_G_01 = (lonL_Color_Pixel_01 - (lonL_Color_B_01 * 65536) _
                                                      - lonL_Color_R_01) / 256
      '
      ' ESTO LO PRESENTAMIOS EN EL LISTBOX
      ' PERO PODRIA HACER OTRAS COSAS...
      List1.AddItem "R=" & lonL_Color_R_01 & " G=" & lonL_Color_G_01 & " B=" & _
      lonL_Color_B_01 & " -- " & RGB(lonL_Color_R_01, _
      lonL_Color_G_01, lonL_Color_B_01)
      ''
   Next
   ''
Next
'--------------------------------------------'
'
''
End Sub

Como veis es solo un pequeño esquema, pero creo que abre bastantes posibilidades para el manipulación de de imágenes.

Acerca de Robert Ale
Soy yo un simple tipo que quiere estar en la red... aunque no se si lo conseguiré algún día...

17 Responses to VB6 – Leer un Pixel de una Imagen

  1. chimos says:

    Que cosas! Me has dejao flipando «en colores»! 😛

  2. Javier Ortíz Aguirre says:

    Hola Roberto, buen día.

    Muchisimas Gracias por tu ayuda… Creo que voy a pedirte una foto para encenderle una veladora.

    Pero, me acabas de encender La Luz del Otro Lado del Tunel.

    Muchas Gracias Nuevamente… A la brevedad posible estaré informando resultados en base a tu Asistencia.

    ¡Saludos!

  3. Iñaki says:

    Buenísimo el código. Andaba yo buscando algo así, pero a la hora de implementarlo me sale un problema. Por favor a ver si me podéis ayudar.
    Ejecutándolo tal cual, saca valores correctos en el listbox, hasta un punto que aparece un error que me dice «Error 5 en tiempo de ejecución – Llamada a procedimiento o argumentos no válidos» y me señala la línea del final de «list1.additem….». Me resulta raro porque si que saca valores hasta un punto y luego señala el error. He cambiado la instrucción que añade a la lista por otras que escribe los valores en un archivo txt y me pasa lo mismo. Inscribe los 389 primeros valores que lee del bmp, pero luego sale el mismo error y señala la línea equvialente, que en este caso es con un «print…». Por qué puede ser eso? Como va hasta un punto y luego no tanto si se pone una instrucción como otra?. Me podéis ayudar? Gracias.

  4. robertale says:

    Hola!

    Cuando salta el error, ¿puedes leer los valores de «lonL_Color_R_01», «lonL_Color_B_01» y «lonL_Color_G_01»?

    Si no es así, el problema puede estar antes.

    A mi me pasaba cuando llegaba a los limites de la imagen, por eso lo del «-1» en los ciclos For.

    Saludos y gracias por leerme!
    Espero tu respuesta.

  5. Iñaki says:

    Gracias robertale.
    Pues los valores que me da en la inspección cuando da el error son lonl_Color_R_01=-1, lonl_Color_B_01=255 y lonl_Color_G_01=-1. Entiendo que el valor negativo es el que da los problemas, pero no tiene sentido. El código lo tengo tal cual el tuyo porque he hecho un copy+paste, y entendía que el -1 en los for iria por ahí los tiros. El error lo da en el pixel 390 que lee cuando tiene 615 de ancho, por lo que no entiendo nada. Se te ocurre algo de por qué puede ser? Ya te digo que el código es idéntico.

    • robertale says:

      Muy raro… pero ya se lo es que!

      El código RGB del color no le veo lógico (-1,255,-1).
      ¿No debería ser (0,255,0), es decir un pixel azul.

      El error es causado por la función «RGB(red, green, blue)», al se un código RGB raro da error.
      Esta función solo admite valores tipo Variant (Integer). Números en el intervalo de 0-255.

      Para solucionarlo se me ocurre que pruebes los siguiente, sustituye la descomposición de colores por:

      lonL_Color_R_01 = lonL_Color_Pixel_01 And &H000000FF&
      lonL_Color_B_01 = (lonL_Color_Pixel_01 And &H0000FF00&) / 256
      lonL_Color_G_01 = (lonL_Color_Pixel_01 And &H00FF0000&) /65535

      Codigo sacado de: http://www.programmersheaven.com/mb/VBasic/273686/273686/getpixel-rgb-value/

      Saludos!

  6. Iñaki says:

    Hola Robertale.
    Ya se lo que pasaba. Al poner el bmp en el picture1, la imagen era grandecita y en el formulario el picture se metia dentro del listbox. Se ve que cuando saca la informaión del picture1, detecta este listbox encima de la imagen y es cuando daba ese valor.
    Por cierto, abusando un poco mas de tu sabiduria, no sabrías cómo puedo leer los pixeles directamente de un archivo .bmp, sin tener que ponerle en ningún control intermedio como el picture?.
    Muchas gracias por compartir tus conocimientos y por tu paciencia.
    Un saludo.

  7. robertale says:

    Paciencia… pero si me anima que algún lea esto jeje
    Y sabiduría… yo diría «moratones» de dar cabezazos contra el monitor jejeje

    Bueno, he encontrado esto.
    Es similar a lo que presento yo solamente que cargando el BMP en memoria.
    No lo he probado pero me a gustado y en cuanto tenga un momento lo pruebo.

    http://www.elguille.info/colabora/vb/antonioMoya_Manejar_bitmapsVB6.htm

    Por cierto recomiendo la pagina del Guille, muchos años de Visual con mucha cosas super interesante.

    Saludos y gracias

    • Iñaki says:

      Hola de nuevo Robertale.

      Siento molestar de nuevo, pero eres la única persona que me ha ayudado muchísimo. Estoy atascado en otra cosa y me he metido en la pagina de el guille pero no he encontrado nada. A ver si me puedes ayudar. Quisiera crear un bmp a partir de otro bmp. O si eso no es posible, crear un bmp al que yo le diga el valor de cada pixel. Se te ocurre algo? Sabes algún sitio donde puedo encontrar algo? Porque llevo días buscando.
      Muchas gracias.

  8. Iñaki says:

    Muchas gracias a ti Robertale, llevo como loco buscando cosas sobre esto y no encuentro nada, y lo poco que he visto es bastante lioso. Me has venido como mano de santo. Muchas gracias. Recomendaré la página a todo el mundo, pero no te creas que conozco mucha gente que programe.

  9. German says:

    Tenia el mismo problema que:
    Iñaki dice:
    7 octubre, 2010 en 17:55
    Gracias robertale.
    Pues los valores que me da en la inspección cuando da el error son lonl_Color_R_01=-1, lonl_Color_B_01=255 y lonl_Color_G_01=-1. Entiendo que el valor negativo es el que da los problemas, pero no tiene sentido. El código lo tengo tal cual el tuyo porque he hecho un copy+paste, y entendía que el -1 en los for iria por ahí los tiros. El error lo da en el pixel 390 que lee cuando tiene 615 de ancho, por lo que no entiendo nada. Se te ocurre algo de por qué puede ser? Ya te digo que el código es idéntico.

    saludos

    • Robert Ale says:

      Hola German,

      Si tu solucion es corta y no te importa compartirla, no estaria mal que la pusieras aqui.

      Muchas gracias por participar!!

      Saludos,
      Robert

  10. mindcedeka says:

    Muy bueno el aporte. Gracias.

  11. Jonas says:

    como puedo comparar 2 imagenes y cuantificar la diferencia en un programa de visual basic

Deja un comentario