How to generate dynamic images for your web application


Typically, a web site might show some pictures. These could be pictures of items for sale from a catalog, personal photos, etc. Usually, the web author places these pictures as files in a directory on the web server, and just puts links to them in the authored web pages.


 


This scheme doesn’t easily allow dynamic pictures.


 



  • Perhaps the author would like to generate the pictures on the fly, when the web page is being rendered in the remote browser

  • Perhaps the picture is in a database, rather than a file on disk

  • Perhaps the author would like to write some text on the picture, such as a copyright notice.

  • Perhaps dynamically created thumbnails or other sizes are desired (my picture application generates different sized images rotated 90 degrees for my SmartPhone, which has higher vertical than horizontal resolution)

  • It’s a way that you can rotate text, use various fonts, sizes, colors.

 


We can generate images dynamically to solve these problems.


 


This sample works in Visual Studio 2005 and Visual Studio 2008: It creates 2 images controls, each with an ImageUrl property specifying to call the default.aspx page with a parameter.


 


I’ve been using this technique of calling the same page with parameters in ASP for years.


 


If the parameter is passed:



  • an empty bitmap object is created

  • a graphics object from that image is created

  • some text is drawn and rotated

  • the image is saved to a memory stream

  • the stream is then written back to the browser.

 


The sample includes code to conditionally choose static images or retrieve images from a table.


 


This technique can easily be applied to an asp:GridView control to show dynamically generated images in a column of a databound grid.


 


(For more on the thumbnail table: Create thumbnails of all your digital photos in a single table)


 


Start Visual Studio


File->New->Web Site.


In the Default.aspx put this text: (or just drag 2 image controls onto the design surface, and set the ImageUrl property)


 


<%@ Page Language=”VB” AutoEventWireup=”false” CodeFile=”Default.aspx.vb” Inherits=”_Default” %>


 


<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>


 


<html xmlns=”http://www.w3.org/1999/xhtml” >


<head runat=”server”>


    <title>Untitled Page</title>


</head>


<body>


    <form id=”form1″ runat=”server”>


    <div>


        this is a test<br />


        <asp:Image ID=”Image1″ ImageUrl=”~/Default.aspx?Imageid=one” runat=”server” />


        <asp:Image ID=”Image2″ ImageUrl=”~/Default.aspx?Imageid=another” runat=”server” /></div>


    </form>


</body>


</html>


 


 


In the Default.aspx.vb file (choose View->Code), paste this:


 


 


Imports System.Drawing


Partial Class _Default


    Inherits System.Web.UI.Page


 


 


    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load


        Dim ImageId As String = Request.QueryString(“ImageId”)    ‘ see if the image is being requested


        If Not ImageId Is Nothing Then


            Dim MyImage As New Bitmap(250, 400)         ‘ create a new blank bitmap


            Dim MyGraphics As Graphics = Graphics.FromImage(MyImage)    ‘ create a Graphics object from the image


            MyGraphics.FillRectangle(Brushes.AliceBlue, MyImage.GetBounds(GraphicsUnit.Pixel))  ‘ back color


            MyGraphics.RotateTransform(45)          ‘ rotate the contents


            MyGraphics.DrawString(” Test string “ + ImageId, New Font(“arial”, 10, FontStyle.Bold), Brushes.Coral, 0, 0)


            Dim mStream As New IO.MemoryStream  ‘ create a place to write the jpg


            MyImage.Save(mStream, Imaging.ImageFormat.Jpeg)


            Dim Bytes() As Byte = New Byte(mStream.Length – 1) {}   ‘ Byte array to store the jpg


            mStream.Seek(0, IO.SeekOrigin.Begin)


            mStream.Read(Bytes, 0, mStream.Length – 1)


            Response.BinaryWrite(Bytes) ‘ write the jpg back to the browser


            Return


 


            ‘ alternatively, something like this can be used


            If ImageId.Length Mod 2 = 1 Then


                Response.BinaryWrite(System.IO.File.ReadAllBytes(Me.MapPath(“~/images/balloon.bmp”)))


            Else


                Response.BinaryWrite(System.IO.File.ReadAllBytes(Me.MapPath(“~/images/beany.bmp”)))


            End If


            Return


 


            ‘ or from a Visual Foxpro database:


            Dim oda As New Data.OleDb.OleDbDataAdapter( _


                    “select * from pixthumb where recno()=” + _


                    ImageId.Length.ToString, _


                “provider=vfpoledb.1;data source=d:\pictures\pixthumb.dbf”)


            Dim dt As New Data.DataTable


            oda.Fill(dt)


            Dim thumb = dt.Rows(0).Item(1)


            Response.BinaryWrite(thumb)


        End If


 


 


    End Sub


End Class


 


End of code


 


Now hit F5 to run the code