En este tutorial veremos cómo crear imágenes dinámicamente desde una página web. A modo de ejemplo desarrollaremos un control para dibujar gráficas de forma dinámica.

En este artículo veremos cómo crear imágenes dinámicamente desde una página web. A modo de ejemplo desarrollaremos un control para dibujar gráficas de forma dinámica.

Nuestro proyecto constará de una página para probar el control llamada inicial.aspx, de nuestro control Imagen y de una página llamada DibujaImagen, que será la encargada de dibujar las imágenes que generemos en dicho control.

Este control para generar una gráfica es bastante sencillo, pero a partir de él se podrían construir otros más complejos para generar diagramas de caja, diagramas de sectores, etc.

 

DESARROLLANDO EL CONTROL:

En nuestro proyecto (del tipo aplicación web) añadiremos una nueva clase a la que llamaremos Imagen, y que heredará del control web Image.

 

Option Strict On

Option Explicit On

Public Class Imagen
Inherits System.Web.UI.WebControls.Image

  

A continuación añadiremos una serie de propiedades: 

  1. –         Valores: es un array de enteros que contendrá todos los valores con los que se construirán las barras.
  2. –         ColorGraficas: color del que se dibujarán las barras.
  3. –         ColorFondo: color del fondo del control.
  4. –         AnchoBarras: ancho de cada una de las barras.
  5. –         SeparacionEntreBarras: separación entre las distintas barras.
  6. –         Encabezado: etiqueta que se mostrará en el encabezado.
  7. –         Pie: etiqueta que se mostrará al pie del diagrama.
  8. –         MostrarValores: booleano que indica si se deben mostrar los valores sobre su respectiva barra.
  9.  

 

Muchas tienen valores por defecto, para que se pueda mostrar la gráfica en tiempo de diseño antes de asignar valores a sus propiedades.

Dim mValores() As Integer = {100, 25, 80, 50, 45}

Public Property Valores() As Integer()

Get

Return mValores

End Get

Set(ByVal Value As Integer())

mValores = Value

End Set

End Property

Dim mColorFondo As Color = Color.Khaki

Public Property ColorFondo() As Color

Get

Return mColorFondo

End Get

Set(ByVal Value As Color)

mColorFondo = Value

End Set

End Property

Dim mColorGraficas As Color = Color.LightBlue

Public Property ColorGraficas() As Color

Get

Return mColorGraficas

End Get

Set(ByVal Value As Color)

mColorGraficas = Value

End Set

End Property

Dim mAnchoBarras As Integer = 20

Public Property AnchoBarras() As Integer

Get

Return mAnchoBarras

End Get

Set(ByVal Value As Integer)

mAnchoBarras = Value

End Set

End Property

Dim mSeparacionEntreBarras As Integer = 20

Public Property SeparacionEntreBarras() As Integer

Get

Return mSeparacionEntreBarras

End Get

Set(ByVal Value As Integer)

mSeparacionEntreBarras = Value

End Set

End Property

Dim mEncabezado As String

Public Property Encabezado() as string

Get

return mEncabezado

End Get

Set(ByVal Value As string)

mEncabezado = Value

End Set

End Property

Dim mPie As String

Public Property Pie() As String

Get

Return mPie

End Get

Set(ByVal Value As String)

mPie = Value

End Set

End Property

Dim mMostrarValores As Boolean

Public Property MostrarValores() As Boolean

Get

Return mMostrarValores

End Get

Set(ByVal Value As Boolean)

mMostrarValores = Value

End Set

End Property

En el constructor de la clase inicializaremos sus dimensiones para que tenga un tamaño inicial.

 

   

Public Sub New()

MyBase.New()

Me.Width = Unit.Pixel(300)

Me.Height = Unit.Pixel(150)

End Sub

 

Como ya comentamos anteriormente, la encargada de dibujar la imagen es la página DibujaImagen, la cual recibirá por querystring todos los parámetros que requiere para dibujar correctamente la gráfica. La llamada a esta página la realizaremos en el procedimiento Render de la clase Imagen, el cual tendremos que sobrescribir.

Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)

Dim strValores As String

strValores = ValoresACadena()

Me.ImageUrl = «DibujaImagen.aspx?ColorFondo=» & mColorFondo.ToKnownColor.ToString & «&ColorGraficas=» & mColorGraficas.ToKnownColor.ToString & «&Ancho=» & Me.Width.Value.ToString & «&Alto=» & Me.Height.Value.ToString & «&AnchoBarras=» & mAnchoBarras.ToString & «&SeparacionEntreBarras=» & SeparacionEntreBarras.ToString & «&Pie=» & mPie & «&Encabezado=» & mEncabezado & «&mostrarValores=» & mMostrarValores & «&valores=» & strValores

MyBase.Render(writer)

End Sub

Private Function ValoresACadena() As String

Dim strValores As String

Dim i As Integer

strValores = «»

For i = 0 To mValores.GetUpperBound(0)

strValores &= «_» & mValores(i).ToString

Next

strValores = strValores.Substring(1) ‘quitamos el primer _

Return strValores

End Function

DESARROLLANDO LA PÁGINA:

Pasemos ahora al código de la página DibujaImagen. Toda la funcionalidad de esta página está dentro del procedimiento que maneja el evento Load, y consiste en dibujar la gráfica en base a los parámetros que ha recibido en la querystring. Instanciaremos un bitmap del tamaño de la imagen y a partir de el obtendremos su objeto Graphics, sobre el que realizaremos todos los dibujos. Finalmente, volcaremos el bitmap en la salida de la página y liberaremos todos los recursos que hemos utilizado.

Option Explicit On

Option Strict On

Public Class DibujaImagen

Inherits System.Web.UI.Page

#Region » Código generado por el Diseñador de Web Forms »

‘El Diseñador de Web Forms requiere esta llamada.

Private Sub InitializeComponent()

End Sub

‘NOTA: el Diseñador de Web Forms necesita la siguiente declaración del marcador de posición.

‘No se debe eliminar o mover.

Private designerPlaceholderDeclaration As System.Object

Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init

‘CODEGEN: el Diseñador de Web Forms requiere esta llamada de método

‘No la modifique con el editor de código.

InitializeComponent()

End Sub

#End Region

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

‘Introducir aquí el código de usuario para inicializar la página

Const MARGEN_SUPERIOR As Integer = 20

Const MARGEN_INFERIOR As Integer = 20

Const MARGEN_IZQUIERDO As Integer = 30 ‘ 20

Const MARGEN_DERECHO As Integer = 20

Dim ancho As Integer

Dim alto As Integer

Dim separacionEntreBarras As Integer

Dim anchoBarras As Integer

Dim colorFondo As String

Dim colorGraficas As String

Dim i As Integer

Dim strValores As String

Dim valores() As String

Dim valor As Integer

Dim maximo As Integer

Dim intervalo As Integer

Dim cadena As String

Dim mostrarValores As Boolean

Dim imgBitmap As Bitmap

Dim graficos As Graphics

Dim lapiz As New Pen(Color.Black)

Dim brocha As SolidBrush = New SolidBrush(Color.Black)

Dim brochaColorGraficas As SolidBrush

colorFondo = Request.Params(«ColorFondo»)

colorGraficas = Request.Params(«ColorGraficas»)

ancho = CInt(Request.Params(«Ancho»))

alto = CInt(Request.Params(«Alto»))

separacionEntreBarras = CInt(Request.Params(«SeparacionEntreBarras»))

anchoBarras = CInt(Request.Params(«AnchoBarras»))

mostrarValores = CBool(Request.Params(«mostrarValores»))

cadena = Request.Params(«Cadena»)

brochaColorGraficas = New SolidBrush(Color.FromName(colorGraficas))

imgBitmap = New Bitmap(ancho, alto)

graficos = Graphics.FromImage(imgBitmap)

graficos.Clear(Color.FromName(colorFondo))

strValores = Request.Params(«Valores»)

valores = strValores.Split(«_».ToCharArray)

maximo = Integer.MinValue

For i = 0 To valores.GetUpperBound(0)

If CInt(valores(i)) > maximo Then maximo = CInt(valores(i))

Next

maximo = CInt(maximo * 1.2)

intervalo = CInt(maximo / 5)

graficos.DrawLine(lapiz, MARGEN_IZQUIERDO, MARGEN_SUPERIOR, MARGEN_IZQUIERDO, alto – MARGEN_INFERIOR) ‘eje vertical

graficos.DrawLine(lapiz, MARGEN_IZQUIERDO – 5, alto – MARGEN_INFERIOR, ancho – MARGEN_DERECHO, alto – MARGEN_INFERIOR) ‘eje horizontal

graficos.DrawLine(lapiz, MARGEN_IZQUIERDO – 5, MARGEN_SUPERIOR, MARGEN_IZQUIERDO + 5, MARGEN_SUPERIOR)

graficos.DrawLine(lapiz, MARGEN_IZQUIERDO – 5, MARGEN_SUPERIOR + CInt((alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5), MARGEN_IZQUIERDO + 5, MARGEN_SUPERIOR + CInt((alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5))

graficos.DrawLine(lapiz, MARGEN_IZQUIERDO – 5, MARGEN_SUPERIOR + CInt(2 * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5), MARGEN_IZQUIERDO + 5, MARGEN_SUPERIOR + CInt(2 * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5))

graficos.DrawLine(lapiz, MARGEN_IZQUIERDO – 5, MARGEN_SUPERIOR + CInt(3 * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5), MARGEN_IZQUIERDO + 5, MARGEN_SUPERIOR + CInt(3 * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5))

graficos.DrawLine(lapiz, MARGEN_IZQUIERDO – 5, MARGEN_SUPERIOR + CInt(4 * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5), MARGEN_IZQUIERDO + 5, MARGEN_SUPERIOR + CInt(4 * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5))

graficos.DrawString((intervalo * 5).ToString, New Font(«Arial», 10), brocha, 2, MARGEN_SUPERIOR – 7)

graficos.DrawString((intervalo * 4).ToString, New Font(«Arial», 10), brocha, 2, CInt((alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5) + MARGEN_SUPERIOR – 7)

graficos.DrawString((intervalo * 3).ToString, New Font(«Arial», 10), brocha, 2, CInt(2 * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5) + MARGEN_SUPERIOR – 7)

graficos.DrawString((intervalo * 2).ToString, New Font(«Arial», 10), brocha, 2, CInt(3 * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5) + MARGEN_SUPERIOR – 7)

graficos.DrawString(intervalo.ToString, New Font(«Arial», 10), brocha, 2, CInt(4 * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5) + MARGEN_SUPERIOR – 7)

Dim puntos(3) As PointF

Dim puntos2(3) As PointF

For i = 0 To valores.GetUpperBound(0)

puntos(0).X = MARGEN_IZQUIERDO + 20 + (i * (separacionEntreBarras + anchoBarras)) + 10

puntos(0).Y = alto – MARGEN_INFERIOR – CInt(CInt(valores(i)) * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo) – 10

puntos(1).X = MARGEN_IZQUIERDO + 20 + (i * (separacionEntreBarras + anchoBarras)) + anchoBarras + 10

puntos(1).Y = alto – MARGEN_INFERIOR – CInt(CInt(valores(i)) * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo) – 10

puntos(2).X = MARGEN_IZQUIERDO + 20 + (i * (separacionEntreBarras + anchoBarras)) + anchoBarras

puntos(2).Y = alto – MARGEN_INFERIOR – CInt(CInt(valores(i)) * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo)

puntos(3).X = MARGEN_IZQUIERDO + 20 + (i * (separacionEntreBarras + anchoBarras))

puntos(3).Y = alto – MARGEN_INFERIOR – CInt(CInt(valores(i)) * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo)

puntos2(0).X = puntos(2).X

puntos2(0).Y = puntos(2).Y

puntos2(1).X = puntos(1).X

puntos2(1).Y = puntos(1).Y

puntos2(2).X = puntos(1).X

puntos2(2).Y = alto – MARGEN_INFERIOR – 10

puntos2(3).X = puntos(2).X

puntos2(3).Y = alto – MARGEN_INFERIOR

Dim camino As New Drawing2D.GraphicsPath

Dim camino2 As New Drawing2D.GraphicsPath

camino.AddPolygon(puntos)

camino2.AddPolygon(puntos2)

graficos.FillRectangle(brochaColorGraficas, MARGEN_IZQUIERDO + 20 + (i * (separacionEntreBarras + anchoBarras)), alto – MARGEN_INFERIOR – CInt(CInt(valores(i)) * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo), anchoBarras, CInt(CInt(valores(i)) * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo))

graficos.FillPath(brochaColorGraficas, camino)

graficos.FillPath(brochaColorGraficas, camino2)

graficos.DrawPath(lapiz, camino)

graficos.DrawPath(lapiz, camino2)

graficos.DrawRectangle(lapiz, MARGEN_IZQUIERDO + 20 + (i * (separacionEntreBarras + anchoBarras)), alto – MARGEN_INFERIOR – CInt(CInt(valores(i)) * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo), anchoBarras, CInt(CInt(valores(i)) * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo))

If mostrarValores Then

graficos.DrawString(valores(i), New Font(«Arial», 8), brocha, MARGEN_IZQUIERDO + 30 + (i * (separacionEntreBarras + anchoBarras)), alto – MARGEN_INFERIOR – CInt(CInt(valores(i)) * (alto – (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo) – 25)

End If

Next

graficos.DrawString(Request.Params(«Pie»), New Font(«Arial», 8), brocha, MARGEN_IZQUIERDO, alto – 15)

graficos.DrawString(Request.Params(«Encabezado»), New Font(«Arial», 8), brocha, MARGEN_IZQUIERDO, 5)

Response.ContentType = «image/jpeg»

imgBitmap.Save(Response.OutputStream, Imaging.ImageFormat.Jpeg)

brochaColorGraficas.Dispose()

brocha.Dispose()

lapiz.Dispose()

graficos.Dispose()

imgBitmap.Dispose()

End Sub

End Class