VB6 – Leer un Pixel de una Imagen
9 septiembre, 2010 17 comentarios
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.
Que cosas! Me has dejao flipando «en colores»! 😛
Muchas Thanks!! 😀
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!
Gracia Javier!
Espero ansioso recibir los comentarios de tus resultados. De esto se puede sacar petroleo!
Saludos cordiales!
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.
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.
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.
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!
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.
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
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.
Hola Iñaki,
A ver que te parece esto?
http://www.cs.uvm.edu/~erickson/education/vb_bmp/BMP.html
Saludos
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.
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
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
Muy bueno el aporte. Gracias.
como puedo comparar 2 imagenes y cuantificar la diferencia en un programa de visual basic