Binary images - thumbnails


J

James Page

Hi all

I have a SQL database where images are stored in a varBinary field. I can
display those images within a image control on a page by using the following:

ImageUrl='<%# Eval("PictureID", "~/ShowPicture.aspx?PictureID={0}") %>'

The image is generated from an aspx page called “showPicture.aspx†using the
following code behind:

Imports System.Data.SqlClient

Partial Class ShowPicture
Inherits System.Web.UI.Page

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Handles Me.Load
Dim PictureID As Integer = Convert.ToInt32(Request.QueryString("PictureID"))

'Connect to the database and bring back the image contents & MIME type for
the specified picture
Using myConnection As New
SqlConnection(ConfigurationManager.ConnectionStrings("ImageGalleryConnectionString").ConnectionString)

Const SQL As String = "SELECT [MIMEType], [ImageData] FROM [Pictures] WHERE
[PictureID] = @PictureID"
Dim myCommand As New SqlCommand(SQL, myConnection)
myCommand.Parameters.AddWithValue("@PictureID", PictureID)

myConnection.Open()

Dim myReader As SqlDataReader = myCommand.ExecuteReader
If myReader.Read Then
Response.ContentType = myReader("MIMEType").ToString()
Response.BinaryWrite(myReader("ImageData"))
End If
myReader.Close()
myConnection.Close()
End Using
End Sub
End Class

The problem I have is that the image control needs to be a thumbnail of the
original image. When I use the above technique the images are not
proprotionately resized to fit the image control width and height – rather
they are stretched to fit.
Can anyone give me some guidance on how once the binary data has been
retrieved it can be proportionatley resized to fit the image control?
Essentialy producing ‘thumbnails’ of the original.

Many thanks
 
Ad

Advertisements

A

Alexey Smirnov

Hi all

I have a SQL database where images are stored in a varBinary field. I can
display those images within a image control on a page by using the following:

ImageUrl='<%# Eval("PictureID", "~/ShowPicture.aspx?PictureID={0}") %>'

The image is generated from an aspx page called “showPicture.aspx” using the
following code behind:

Imports System.Data.SqlClient

Partial Class ShowPicture
Inherits System.Web.UI.Page

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Handles Me.Load
Dim PictureID As Integer = Convert.ToInt32(Request.QueryString("PictureID"))

'Connect to the database and bring back the image contents & MIME type for
the specified picture
Using myConnection As New
SqlConnection(ConfigurationManager.ConnectionStrings("ImageGalleryConnectio­nString").ConnectionString)

Const SQL As String = "SELECT [MIMEType], [ImageData] FROM [Pictures] WHERE
[PictureID] = @PictureID"
Dim myCommand As New SqlCommand(SQL, myConnection)
myCommand.Parameters.AddWithValue("@PictureID", PictureID)

myConnection.Open()

Dim myReader As SqlDataReader = myCommand.ExecuteReader
If myReader.Read Then
Response.ContentType = myReader("MIMEType").ToString()
Response.BinaryWrite(myReader("ImageData"))
End If
myReader.Close()
myConnection.Close()
End Using
End Sub
End Class

The problem I have is that the image control needs to be a thumbnail of the
original image. When I use the above technique the images are not
proprotionately resized to fit the image control width and height – rather
they are stretched to fit.
Can anyone give me some guidance on how once the binary data has been
retrieved it can be proportionatley resized to fit the image control?
Essentialy producing ‘thumbnails’ of the original.

Many thanks

I am sure you will find many examples in google. Here's the one, which
could help you. Hope it works :)


Response.ContentType = myReader("MIMEType").ToString()
Dim content As Byte() = CByte(myReader("ImageData"))

lnWidth = 100
lnHeight = 100

Dim s As New MemoryStream(content)
Dim image As New Bitmap(s)

Dim bmpOut As System.Drawing.Bitmap

Try
Dim loBMP As New Bitmap(s)
Dim loFormat As ImageFormat = loBMP.RawFormat
Dim lnRatio As Decimal
Dim lnNewWidth As Integer = 0
Dim lnNewHeight As Integer = 0

If loBMP.Width > loBMP.Height Then
lnRatio = CDec(lnWidth) / loBMP.Width
lnNewWidth = lnWidth
Dim lnTemp As Decimal = loBMP.Height * lnRatio
lnNewHeight = CInt(lnTemp)
Else
lnRatio = CDec(lnHeight) / loBMP.Height
lnNewHeight = lnHeight
Dim lnTemp As Decimal = loBMP.Width * lnRatio
lnNewWidth = CInt(lnTemp)
End If

bmpOut = New Bitmap(lnNewWidth, lnNewHeight)
Dim g As Graphics = Graphics.FromImage(bmpOut)
g.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
g.FillRectangle(Brushes.White, 0, 0, lnNewWidth, lnNewHeight)
g.DrawImage(loBMP, 0, 0, lnNewWidth, lnNewHeight)

loBMP.Dispose()
Catch
Return
End Try

stream.Close()
stream.Dispose()

Try
bmp.Save(Response.OutputStream,
System.Drawing.Imaging.ImageFormat.Jpeg)
Catch
Finally
bmp.Dispose()
End Try
 
J

James Page

Thanks Alexey

But having problems:
Here is the revised code:

Imports System.Data.SqlClient
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Imaging

Partial Class showPicture
Inherits System.Web.UI.Page

Protected Sub Page_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
Dim ID As Integer = Convert.ToInt32(Request.QueryString("PictureID"))

'Connect to the database and bring back the image contents & MIME
type for the specified picture
Using myConnection As New
SqlConnection(ConfigurationManager.ConnectionStrings("picturesConnectionString").ConnectionString)

Const SQL As String = "SELECT [ID], [MIMEtype], [Image] FROM
[Pictures] WHERE [ID] = @PictureID"
Dim myCommand As New SqlCommand(SQL, myConnection)
myCommand.Parameters.AddWithValue("@PictureID", ID)

myConnection.Open()
Dim myReader As SqlDataReader = myCommand.ExecuteReader

If myReader.Read Then
Response.ContentType = myReader("MIMEtype").ToString()
'Response.BinaryWrite(myReader("Image"))
Dim content As Byte() = CByte(myReader("image"))
End If

Dim lnWidth As Integer = 100
Dim lnHeight As Integer = 100

Dim s As New MemoryStream(Content)
Dim image As New Bitmap(s)

Dim bmpOut As System.Drawing.Bitmap

Try
Dim loBMP As New Bitmap(s)
Dim loFormat As ImageFormat = loBMP.RawFormat
Dim lnRatio As Decimal
Dim lnNewWidth As Integer = 0
Dim lnNewHeight As Integer = 0

If loBMP.Width > loBMP.Height Then
lnRatio = CDec(lnWidth) / loBMP.Width
lnNewWidth = lnWidth
Dim lnTemp As Decimal = loBMP.Height * lnRatio
lnNewHeight = CInt(lnTemp)
Else
lnRatio = CDec(lnHeight) / loBMP.Height
lnNewHeight = lnHeight
Dim lnTemp As Decimal = loBMP.Width * lnRatio
lnNewWidth = CInt(lnTemp)
End If

bmpOut = New Bitmap(lnNewWidth, lnNewHeight)
Dim g As Graphics = Graphics.FromImage(bmpOut)
g.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic()
g.FillRectangle(Brushes.White, 0, 0, lnNewWidth, lnNewHeight)
g.DrawImage(loBMP, 0, 0, lnNewWidth, lnNewHeight)

loBMP.Dispose()
Catch
Return
End Try

stream.Close()
stream.Dispose()

Try
bmp.Save(Response.OutputStream,
System.Drawing.Imaging.ImageFormat.Jpeg)
Catch
Finally
bmp.Dispose()
End Try
End Using
End Sub
End Class


However line 25: Dim content As Byte() = CByte(myReader("image"))
shows an error ("Value of type byte cannot be converted to 1 dimentional
array of byte)

And I'm having problems with:
line 31: Dim s As New MemoryStream(Content)
shows an error (Content is a type and cannot be used as an expression)

Line 57: g.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic()
Shows an error (Expression is not an array or method and cannot have an
arguement list)

Lines 66 & 67:
stream.Close()
stream.Dispose()

Shows an error: (reference to a non shared member requires an object
reference)

Finaly lines 70 & 73 reference a 'bmp' how do I declare that - dim bmp as
new bitmap?

I'm keen to sort this out as I have tried many ways to get a proportional
thumbnail without success!!

Thanks
 
J

James Page

Hi Alexey

Just got this working: Heres the code

Imports System.Data.SqlClient
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Imaging

Partial Class showPicture
Inherits System.Web.UI.Page

Protected Sub Page_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
Dim ID As Integer = Convert.ToInt32(Request.QueryString("PictureID"))

'Connect to the database and bring back the image contents & MIME
type for the specified picture
Using myConnection As New
SqlConnection(ConfigurationManager.ConnectionStrings("picturesConnectionString").ConnectionString)

Const SQL As String = "SELECT [ID], [MIMEtype], [Image] FROM
[Pictures] WHERE [ID] = @PictureID"
Dim myCommand As New SqlCommand(SQL, myConnection)
myCommand.Parameters.AddWithValue("@PictureID", ID)

myConnection.Open()
Dim myReader As SqlDataReader = myCommand.ExecuteReader

If myReader.Read Then
Response.ContentType = myReader("MIMEtype").ToString()
End If
Dim content As Byte() = (myReader("Image"))

Dim lnWidth As Integer = 200
Dim lnHeight As Integer = 200

Dim s As New MemoryStream(content)
Dim image As New Bitmap(s)

Dim bmpOut As System.Drawing.Bitmap

Try
Dim loBMP As New Bitmap(s)
Dim loFormat As ImageFormat = loBMP.RawFormat
Dim lnRatio As Decimal
Dim lnNewWidth As Integer = 0
Dim lnNewHeight As Integer = 0

If loBMP.Width > loBMP.Height Then
lnRatio = CDec(lnWidth) / loBMP.Width
lnNewWidth = lnWidth
Dim lnTemp As Decimal = loBMP.Height * lnRatio
lnNewHeight = CInt(lnTemp)
Else
lnRatio = CDec(lnHeight) / loBMP.Height
lnNewHeight = lnHeight
Dim lnTemp As Decimal = loBMP.Width * lnRatio
lnNewWidth = CInt(lnTemp)
End If

bmpOut = New Bitmap(lnNewWidth, lnNewHeight)
Dim g As Graphics = Graphics.FromImage(bmpOut)
g.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
g.FillRectangle(Brushes.White, 0, 0, lnNewWidth, lnNewHeight)
g.DrawImage(loBMP, 0, 0, lnNewWidth, lnNewHeight)

loBMP.Dispose()
Catch
Return
End Try

myConnection.Close()
myReader.Dispose()

Try
bmpOut.Save(Response.OutputStream,
System.Drawing.Imaging.ImageFormat.Jpeg)
Catch
Finally
bmpOut.Dispose()
End Try
End Using
End Sub
End Class


All I need to do now is position the resultant thumbnail in a div correctly
and were done - hurrah!!

Thanks for your help Alexey
 
Ad

Advertisements

A

Alexey Smirnov

Hi Alexey

Just got this working: Heres the code

Imports System.Data.SqlClient
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Imaging

Partial Class showPicture
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
        Dim ID As Integer = Convert.ToInt32(Request.QueryString("PictureID"))

        'Connect to the database and bring back the image contents & MIME
type for the specified picture
        Using myConnection As New
SqlConnection(ConfigurationManager.ConnectionStrings("picturesConnectionStr­ing").ConnectionString)

            Const SQL As String = "SELECT [ID], [MIMEtype], [Image] FROM
[Pictures] WHERE [ID] = @PictureID"
            Dim myCommand As New SqlCommand(SQL, myConnection)
            myCommand.Parameters.AddWithValue("@PictureID", ID)

            myConnection.Open()
            Dim myReader As SqlDataReader = myCommand.ExecuteReader

            If myReader.Read Then
                Response.ContentType = myReader("MIMEtype").ToString()
            End If
            Dim content As Byte() = (myReader("Image"))

            Dim lnWidth As Integer = 200
            Dim lnHeight As Integer = 200

            Dim s As New MemoryStream(content)
            Dim image As New Bitmap(s)

            Dim bmpOut As System.Drawing.Bitmap

            Try
                Dim loBMP As New Bitmap(s)
                Dim loFormat As ImageFormat = loBMP.RawFormat
                Dim lnRatio As Decimal
                Dim lnNewWidth As Integer = 0
                Dim lnNewHeight As Integer = 0

                If loBMP.Width > loBMP.Height Then
                    lnRatio = CDec(lnWidth) / loBMP..Width
                    lnNewWidth = lnWidth
                    Dim lnTemp As Decimal = loBMP.Height * lnRatio
                    lnNewHeight = CInt(lnTemp)
                Else
                    lnRatio = CDec(lnHeight) / loBMP.Height
                    lnNewHeight = lnHeight
                    Dim lnTemp As Decimal = loBMP.Width * lnRatio
                    lnNewWidth = CInt(lnTemp)
                End If

                bmpOut = New Bitmap(lnNewWidth, lnNewHeight)
                Dim g As Graphics = Graphics.FromImage(bmpOut)
                g.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
                g.FillRectangle(Brushes.White, 0, 0, lnNewWidth, lnNewHeight)
                g.DrawImage(loBMP, 0, 0, lnNewWidth, lnNewHeight)

                loBMP.Dispose()
            Catch
                Return
            End Try

            myConnection.Close()
            myReader.Dispose()

            Try
                bmpOut.Save(Response.OutputStream,
System.Drawing.Imaging.ImageFormat.Jpeg)
            Catch
            Finally
                bmpOut.Dispose()
            End Try
        End Using
    End Sub
End Class

All I need to do now is position the resultant thumbnail in a div correctly
and were done - hurrah!!

Thanks for your help Alexey

Great, glad it works :)
 

Top