28 agosto 2011

Bitmaps y Visual Basic

super-mario-bros-8bitEn mensajes anteriores he hablado de la forma de aprovechar el GDI+ que viene con Visual Basic .net para usar la clase Graphics para dibujar líneas y cuadrados al azar, hacer un especie de Paint chafa y luego lo combinamos con menús para que la interfaz se viera bien.  En esta ocasión haré uso de la clase Bitmap y un PictureBox para crear una superficie que me permita dibujar sobre él mediante código.  Con esto podremos hacer animaciones basados en Sprites, lo cual es la base de todas las animaciones que se hacen en los videojuegos 2D.

Para dibujar mediante el código, se necesitan objetos de la clase Bitmap y Graphics, que puedo declarar de la siguiente manera:

Public superficie As Bitmap
Public disp as Graphics

Luego, suponiendo que tengo un PictureBox llamado PictureBox1, creo los objetos.  Aunque el PictureBox se puede crear a la hora de ejecución, en esta ocasión voy a hacerlo de forma manual (o sea, dibujándolo en la pantalla).  El código se vería así:

superficie = New Bitmap(Me.Size.Width,Me.Size.Height)
PictureBox1.Image = superficie
disp = Graphics.FromImage(superficie)

Con esto ya inicializamos los objetos que necesitamos para seguir.

Cargando un bitmap a la memoria

Para crear un nuevo bitmap (o mapa de bits en español), no hay una función que la cargue de forma automática.  Hay que hacer uso del constructor de la clase de la siguiente manera:

Public bmp As Bitmap
bmp = New Bitmap(“imagen.bmp”)

Aunque se podría declarar y llamar el constructor al mismo tiempo, no lo voy a hacer para tener mayor control sobre el proceso.  El hacerlo en 2 líneas (muy a pesar de que me gusta ahorrar líneas de código) me permite usar un bloque Try…Catch (ya en varios posts he explicado la forma en que nos podemos recuperar de errores con estas instrucciones) para asegurarme que se haya podido cargar a la memoria sin problemas.  El´código quedaría así:

Try 
    bmp = New Bitmap(“imagen.bmp”)
Catch ex As Exception
    MsgBox(“Error al cargar el archivo”)
End Try

Para simplificarnos la vida, sería conveniente hacer una función que cargue un mapa de bits a la memoria y devolviera un objeto Bitmap si lo puede abrir o un Nothing (valor nulo) si no es posible (ya sea que no está el archivo o está dañado o lo que sea).  Una función de este tipo sería como esto:

Public Function CargaBitmap(ByVal NombreArchivo As String)
    Dim bmp As Bitmap
    Try
        bmp = New Bitmap(NombreArchivo)
    Catch ex As Exception
        MsgBox(“Error al cargar el archivo”)
    End Try
End Function
 

Creo que con una función como esta nos simplificamos la vida muchísimo.  Ahora, ¡a continuar con la aventura!

Dibujando un mapa de bits en la ventana

Hay varias versiones de la función Graphics.DrawImage() lo que en términos de la OOP (Programación Orientada a Objetos, por sus siglas en inglés) diríamos que son funciones sobrecargadas.  Independientemente del término rimbombante que le quieras poner, la versión más simple solo recibe las coordenadas horizontales (X), verticales (Y) y el mapa de bits a dibujar.  Por ejemplo, para dibujar un bitmap (suponiendo que estás usando los mismos nombres que he usado para objetos en este post) en la coordenada 15,20 escribiría lo siguiente:

disp.DrawImage(bmp,15,20)

Esta función también acepta otros dos enteros que indican el ancho y alto a los que se mostrará haciendo que la imagen cambie de tamaño (120 pixeles de ancho por 120 de alto):

disp.DrawImage(bmp,15,20,120,120)

Girando y volteando el mapa de bits

Además de cambiar el tamaño, hay otras cuantas maneras de manipular el mapa de bits en tu ventana.  Por ejemplo, se puede girar en 90, 180 y 270 grados y/o voltear tanto de forma horizontal o vertical.  Por ejemplo, si quiero girar un mapa de bits 90o escribiría:

bmp.RotateFlip(RotateFlipType.Rotate90FlipNone)

Para mayores informes sobre la función RotateFlip, qué mejor que preguntarle a Microsoft aquí y si quieres saber todas las opciones de giros, vueltas y revueltas (yo solo puse uno), fíjate en su información acerca de la enumeración RotateFlipType aquí para que seas capaz de hacer todo tipo de malabares con mapas de bits.

Accesando a los pixeles del mapa de bits

También es posible tener acceso a cada pixel del mapa de bits.  Para eso está la función GetPixel() a la que le paso las coordenadas y devuelve un objeto Color con el color que hay en esa posición.  De la misma manera funciona la función (valga la redundancia) SetPixel(), solo que éste último establece un color, lo “pinta” del color que quieres.  Por ejemplo, supongamos que quiero que un mapa de bits se vea como recién sacado de la Matrix (o sea en tono verde), podríamos hacerlo con este código:

For x = 0 To bmp.Width – 1
    For y = 0 To bmp.Height – 1
        Dim ColorActual As Color = bmp.GetPixel(x, y)
        Dim ColorNuevo As Color = Color.FromArgb(0, ColorActual.G, 0)
        bmp.SetPixel(x, y, ColorNuevo)
    Next
Next

Solo una cosa que recordar antes de terminar.  Pese a que Visual Basic 2010 tiene muchas funciones para manipular mapas de bits, tiene sus límites.  No es un programa de diseño ni de dibujo. No se compara al Photoshop ni siquiera al pinchurriento Paint que viene con Windows.  Dicho esto, creo que terminé.

Agradecimientos y referencias

Imagen de Mario en 8 bits cortesía de T&S Web Design.  Y gran parte de lo que escribí aquí, fue asesorado por este libro:

Publicar un comentario
Related Posts Plugin for WordPress, Blogger...