The Artima Developer Community
Sponsored Link

.NET Buzz Forum
Images, Thumbnails, SQL Server, and ASP .NET - Level 200

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Eric Wise

Posts: 126
Nickname: ewise
Registered: Apr, 2005

Eric Wise is a senior .NET consultant.
Images, Thumbnails, SQL Server, and ASP .NET - Level 200 Posted: May 15, 2005 8:35 PM
Reply to this message Reply

This post originated from an RSS feed registered with .NET Buzz by Eric Wise.
Original Post: Images, Thumbnails, SQL Server, and ASP .NET - Level 200
Feed Title: Eric Wise
Feed URL: /error.htm?aspxerrorpath=/blogs/eric.wise/rss.aspx
Feed Description: Business & .NET
Latest .NET Buzz Posts
Latest .NET Buzz Posts by Eric Wise
Latest Posts From Eric Wise

Advertisement

Ok, it's been a bit of time since I posted some technical content.  I seem to be the only codebetter blogger who has big business aspirations and is launching a real ISV so I've been trying to mix that content into the Codebetter feed for those of you who have similar aspirations.  I think it's time to get back to some technical content though.

Using SQL Server to manage images (or other files) is a frequently asked question of mine.  I have come across several clients in my consulting career where they were simply dumping the files into a physical directory on the webserver.  In the end, this is pretty sloppy and difficult to manage especially if for some reason you want to reorganize the data.

In this article I will show you the Easy Assets .NET method of handling image uploads.  The application allows clients to store images of their assets, mostly for insurance purposes.  I had a few goals for this section of the application as follows:

  1. Store images in sql server for easy management on my end.
  2. Automatically compress images so I don't have to worry about disk space usage or demand that my users compress it themselves which can be hard for a user without computer savvy (once again, EASY assets .net)
  3. Generate thumbnails for display in a list.

Step 1: Configuring SQL Server

First thing we must do is set up a SQL Server table to handle the data.  SQL Server has a handy image field to handle this type of thing.  Here's the table we'll be using in the example:

CREATE TABLE [dbo].[AssetImages] (
    [AssetImageID] [int] IDENTITY (1, 1) NOT NULL ,
    [AssetID] [int] NOT NULL ,
    [FileData] [image] NOT NULL ,
    [FileName] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
    [FileSize] [bigint] NOT NULL ,
    [ContentType] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
    [Thumbnail] [image] NOT NULL ,
    [LastEditUser] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
    [LastEditDateTime] [datetime] NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

The main image will be stored in the FileData field and the thumbnail image will be stored in the Thumbnail field.

 

Step 2: Compressing the image

To compress the image, I used the handy tool I mentioned in this post.  You simply register the dll, and drag and drop the compressor tool onto the page.  The following code uploads an image from the html file upload object, compresses it, and then generates a thumbnail.  It uses my domain pattern, like all pages in Easy Assets .NET.

    Private Sub btnUpload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpload.Click
        Try
            Dim upfile As HttpPostedFile = UploadFile.PostedFile
            ' Make sure there's actually content uploaded
 
            If upfile.ContentLength <> Nothing Then
                Dim myData() As Byte
                Dim stream As New MemoryStream
                Dim assetImage As New EasyAssets.DAC.AssetImage
 
                myData = ImageOptimizer1.Optimize(upfile)
                assetImage.FileSize = Convert.ToInt32(myData.Length / 1000)
 
                Dim i As Integer = InStrRev(upfile.FileName.Trim, "\")
                If i = 0 Then
                    assetImage.FileName = upfile.FileName.Trim
                Else
                    assetImage.FileName = Right(upfile.FileName.Trim, Len(upfile.FileName.Trim) - i)
                End If
 
                assetImage.AssetID = Convert.ToInt32(Request.QueryString("AID"))
                assetImage.FileData = myData
                assetImage.ContentType = upfile.ContentType
 
                Dim thumbnail As Bitmap = CreateThumbNail(New Bitmap(upfile.InputStream, False), 120, 120)
 
                thumbnail.Save(stream, ImageFormat.Jpeg)
                assetImage.Thumbnail = stream.GetBuffer()
 
                DomainManager.Save(assetImage)
                BindDataGrid()
            End If
        Catch ex As Exception
            WriteMessage(ex.Message, True)
        End Try
    End Sub

Few things to note:

  1. Filesize / 1000... default is bytes, I convert it to kilobytes.
  2. Bitmaps and memory streams are pretty cool, I know that the bitmap has a thumbnail creation method on it but I've heard that it doesn't do a nice job.  I found the following code on a MVP's site, sorry to whoever it was, I cleared my history and lost your blog.  Contact me and I'll give you proper credit.
    Private Function CreateThumbNail(ByVal postedFile As Bitmap, ByVal width As Integer, ByVal height As Integer) As Bitmap
        Dim bmpOut As System.Drawing.Bitmap
        Dim Format As ImageFormat = postedFile.RawFormat
        Dim Ratio As Decimal
        Dim NewWidth As Integer
        Dim NewHeight As Integer
 
        '*** If the image is smaller than a thumbnail just return it
        If postedFile.Width < width AndAlso postedFile.Height < height Then
            Return postedFile
        End If
 
        If (postedFile.Width > postedFile.Height) Then
            Ratio = Convert.ToDecimal(width / postedFile.Width)
            NewWidth = width
 
            Dim Temp As Decimal = postedFile.Height * Ratio
            NewHeight = Convert.ToInt32(Temp)
        Else
            Ratio = Convert.ToDecimal(height / postedFile.Height)
            NewHeight = height
 
            Dim Temp As Decimal = postedFile.Width * Ratio
            NewWidth = Convert.ToInt32(Temp)
        End If
 
        bmpOut = New Bitmap(NewWidth, NewHeight)
 
        Dim g As Graphics = Graphics.FromImage(bmpOut)
        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
        g.FillRectangle(Brushes.White, 0, 0, NewWidth, NewHeight)
        g.DrawImage(postedFile, 0, 0, NewWidth, NewHeight)
 
        postedFile.Dispose()
 
        Return bmpOut
    End Function

 

Step 3: Binding thumbnails to a datagrid

Now, by default, you can't really show image data from sql server into a datagrid, so we have to sort of "trick" ASP .NET into inserting an image into the grid.  We do this by calling a special aspx page into the template column of the grid.  Here's how it works:

First, set up the template column of the grid as such:

Notice the call to the two pages, on click of the thumbnail I want to show them the full-size version of the photo in a popup window.  The thumbnail is bound to a function called "formaturl" that takes the id of the image as a parameter.  Let's take a look at this function:

    Protected Function FormatURL(ByVal imageID As Integer) As String
        Return ("AssetShowThumb.aspx?id=" & imageID.ToString())
    End Function

So basically we have told asp.net that the source of this image is the results of the AssetShowThumb.aspx.  But what does this page do?  Let's take a look:

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        If Not Page.IsPostBack Then
            Dim assetImg As New EasyAssets.DAC.AssetImage(Convert.ToInt32(Request.QueryString("ID")))
            assetImg = DirectCast(DomainManager.Load(assetImg), EasyAssets.DAC.AssetImage)
 
            Response.ContentType = "Image/JPEG"
            Response.BinaryWrite(assetImg.Thumbnail)
        End If
    End Sub

So all we've done is load the image record, set the content type to jpeg (I force all saves in the above function to be jpegs), and binary write the image data.  We end up with a display like this:

And an original image (on click of thumb) like this:

And oh how I wish this picture, from my hawaii trip, was actually an asset of mine. =)

Read: Images, Thumbnails, SQL Server, and ASP .NET - Level 200

Topic: Update on Koders.com - the search engine for OS code Previous Topic   Next Topic Topic: Meet the robots

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use