Rendering Images in ASP.NET Directly from Your Database, Page 3
After adding a UserControl to your project, add an Image property and a method that sends the image to the HttpResponse stream. RenderImage shows a couple variations of the image rendering. GIFs use indexes into a color palette, so the best result seems to be simply adding the raw bytes to the response stream. If you use something like JPG files, you can use the last #Else condition block, which is pretty straightforward.
Placing the UserControl on a Designated Page
You have the UserControl. Now, youneed a page. The reason for the UserControl and Page is that writing to the HttpResponse stream directly is destructive; if you wrote right to the page that ultimately will contain your images, you would wipe everything else out of the page. (I suspect there is a way to inject the image in a non-destructive way, but I haven't quite perfected it yet.)
The next step is to add a page, drop the UserControl on the page, and coordinate associating each unique ID with the UserControl on each page. Listing 4 contains the code for the page that will play the role of the image source.
Listing 4: The Page_Load event coordinates which image is shown in any specific page and UserControl pair.
Imports System.Drawing Imports System.Drawing.Imaging Imports System.Collections.Generic Partial Class ProductImage Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load If (Request.QueryString("id") Is Nothing) Then Return FId = CType(Request.QueryString("id"), Integer) Dim list As List(Of ProductPhoto) = CType(Session("data"), _ List(Of ProductPhoto)) Dim o As ProductPhoto = list.Find(AddressOf Match) If (o Is Nothing = False) Then FImage = o.LargePhoto End If End Sub Private FId As Integer Private Function Match(ByVal o As ProductPhoto) As Boolean Return o.ProductPhotoID = FId End Function Private FImage As Image Public Property TheImage() As System.Drawing.Image Get Return FImage End Get Set(ByVal value As System.Drawing.Image) FImage = value End Set End Property Protected Sub Page_PreRender(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.PreRender ImageControl1.TheImage = FImage End Sub End Class
The Page_Load event is looking for a QueryString indexed by the string "id". The QueryString—~/ProductImage.aspx?id=1, for example—indicates which key is used to determine which record this page instance is responsible for. Next, you get the List(Of ProductPhoto) objects from session, and finally use List(Of T).Find to search the list for the page's ProductPhoto. Find takes a predicate—think a where condition—and sets the found Image property of the contained Image control.
Figure 2: A visualization depicting the relationship between the page containing the rendered image and the <img> control that uses the page as the image source.
Loading the Page as an Image Control's Source
The final step is to get a list of ProductPhoto objects, stuff those in session, and associate a dynamic path with the ImageUrl (or src) attribute of the image control. Typically, the ImageUrl (or src) attributes have been images; however, by using a page you effectively can obtain a dynamic palette on which to draw. Listing 5 shows a page that consumes the image loaded from a database, and Listing 6 shows the ASPX that binds a page path with the query string. Finally, the rendered images are shown in Figure 3.