Retrieving Image from database & Image resizing

In this post, we will see how to retrieve image(BLOB data) saved in SQL server and display in an image control in the web page. In addition to retrieving image from the SQL server, we will resize the image so that it will keep its preportional width and height.

Assume we need to disply the image in an image control ‘imgUserImage‘ in a page, say MyPage.aspx. To set the ImageUrl property of this image control, we need to create one more aspx page which will return the appropriate image. This new aspx page can be used to retrieve image from the database and resize.

Below is the function which select the image from the database and return as Byte. Put this function in a class file.


public static byte[] GetImage(int ImageID)
{
byte[] functionReturnValue = null;
functionReturnValue = null;
SqlClient.SqlConnection SQLConnection = new SqlClient.SqlConnection(ABC.Common.ConnectionString);
SqlClient.SqlCommand SQLCommand = new SqlClient.SqlCommand("SELECT Image FROM Images WHERE ImageID=@ImageID", SQLConnection);
SQLCommand.Parameters.Add(ABC.Common.CreateSQLParameter("@ImageID", SqlDbType.Int, ImageID));
try
{
SQLConnection.Open();
SqlClient.SqlDataReader SQLReader = SQLCommand.ExecuteReader;
SQLReader.Read();
if (SQLReader.HasRows)
{
Drawing.Image Image = (Drawing.Image)ABC.Serialization.DeSerializeToImage((byte[])SQLReader.Item("Image"), SerializationFormat.Binary);
IO.MemoryStream MemoryStream = new IO.MemoryStream();
Image.Save(MemoryStream, Drawing.Imaging.ImageFormat.Jpeg);
functionReturnValue = MemoryStream.ToArray;
MemoryStream.Close();
}
SQLReader.Close();
}
catch (Exception ex)
{
throw ex;
}
finally
{
SQLConnection.Dispose();
}
return functionReturnValue;
}


Create one aspx page,say ImageGraber.aspx and add the below function in the page load.


if (Request.QueryString("ImageID") != null)
{
byte[] arrContent = null;
if (!string.IsNullOrEmpty(Request.QueryString("ImageID")))
{
arrContent = (byte[])ABC.Image.GetImage(Request.QueryString("ImageID"));
string conType = "image/jpeg";
Response.ContentType = conType;
if (arrContent != null)
{
Bitmap btmap = (Bitmap)Bitmap.FromStream(new MemoryStream(arrContent));
Bitmap bmp = CreateThumbnail(btmap, 500, 500);// specify the width and height of the image
if (bmp == null)
{
this.ErrorResult();
return;
}
string OutputFilename = null;
OutputFilename = Request.QueryString("OutputFilename");
if (OutputFilename != null)
{
if (string.IsNullOrEmpty(this.User.Identity.Name))
{
// *** Custom error display here
bmp.Dispose();
this.ErrorResult();
}
try
{
bmp.Save(OutputFilename);
}
catch (Exception ex)
{
bmp.Dispose();
this.ErrorResult();
return;
}
}
// Put user code to initialize the page here
Response.ContentType = "image/jpeg";
bmp.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
bmp.Dispose();
}
else
{
Drawing.Image.FromFile(Server.MapPath("~/Images/NoImage.jpg")).Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
else
{
Drawing.Image.FromFile(Server.MapPath("~/Images/NoImage.jpg")).Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
}
Response.End();
}


Ofcourse, you need to add two more functins which are called from the above code. First one is ErrorResult()



private void ErrorResult()
{
Response.Clear();
Response.StatusCode = 404;
Response.End();
}



Another function is CreateThumbnail() which is actually doing the image resizing, keeping the image’s height and width proportion. Add the CreateThumbnail() function in the page ImageGrabber.aspx


public static Bitmap CreateThumbnail(Bitmap loBMP, int lnWidth, int lnHeight)
{
System.Drawing.Bitmap bmpOut = null;
try
{
ImageFormat loFormat = loBMP.RawFormat;
decimal lnRatio = default(decimal);
int lnNewWidth = 0;
int lnNewHeight = 0;

//*** If the image is smaller than a thumbnail just return it

if (loBMP.Width < lnWidth && loBMP.Height < lnHeight)
{
return loBMP;

}

if (loBMP.Width > loBMP.Height)
{
lnRatio = (decimal)lnWidth / loBMP.Width;
lnNewWidth = lnWidth;
decimal lnTemp = loBMP.Height * lnRatio;
lnNewHeight = (int)lnTemp;
}
else
{
lnRatio = (decimal)lnHeight / loBMP.Height;
lnNewHeight = lnHeight;
decimal lnTemp = loBMP.Width * lnRatio;
lnNewWidth = (int)lnTemp;
}

bmpOut = new Bitmap(lnNewWidth, lnNewHeight);
Graphics g = 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 null;
}
return bmpOut;
}


Now we will set the ImageUrl property of our image control ‘imgUserImage‘ in the ‘MyPage.aspx‘ as


imgUserImage.ImageUrl = "~/ImageGrabber.aspx?ImageID=" + MemberPictureID + "&ImageType=MemberPictures";


Thats it;

CSS Margin Vs Padding

Sometime we confused of the usage of the CSS properties margin and padding. It will be confusing the context of the usage of margin and padding, if we really don’t know the difference between them.

What is Margin: The CSS margin properties define the space around elements. When you want spaces between two elements, then you can use Margin property.

What is Padding: The CSS padding properties define the space between the element border and the element content. Element content may be text or another element.

In the example below, notice the distance between the first two elements. The distance is 50px as we mentioned it as ‘margin: 50px;

Check the last, we given ‘padding: 40px;‘ so the border and the text ‘Padding Example‘ keeps the distance of 40 pixels.
margin_vs_padding

margin_vs_padding

To get a good idea on margin, padding, border etc. checkout this site http://www.redmelon.net/tstme/box_model/ . The site has a very good example which shows difference graphically.

Encrypting / Decrypting Querystring

Using Query String to pass data between pages is very common in web application. However this gives the visitor the opportunity of modifying a query string and ofcourse is certainly a potential security threat.

Security or not, sometimes you just don’t want the visitors to see all the query strings for whatever reason. In that type of cases we can encrypt the query string and pass it along with the the URL. In the receiving page, we can decrypt the URL and use like ordinary Query string.

The function for encrypting the query string is below:

Public Shared Function TamperProofStringEncode(ByVal value As String, ByVal key As String) As String


Dim mac3des As New   System.Security.Cryptography.MACTripleDES()
Dim md5 As New System.Security.Cryptography.MD5CryptoServiceProvider()
mac3des.Key = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(key))
Return Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(value)) + "-"c + Convert.ToBase64String(mac3des.ComputeHash(System.Text.Encoding.UTF8. _
GetBytes(value)))


End Function

The function for decrypting the query string is below:

Public Shared Function TamperProofStringDecode(ByVal value As String, ByVal key As String) As String


Dim dataValue As String = ""
Dim calcHash As String = ""
Dim storedHash As String = ""

Dim mac3des As New System.Security.Cryptography.MACTripleDES()
Dim md5 As New System.Security.Cryptography.MD5CryptoServiceProvider()
mac3des.Key = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(key))

Try
Dim dValue As String() = value.Split("-"c)
dataValue = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(dValue(0)))
storedHash = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(dValue(1).Replace(" ", "+")))
calcHash = System.Text.Encoding.UTF8.GetString(mac3des.ComputeHash(System.Text. _
Encoding.UTF8.GetBytes(dataValue)))

If storedHash calcHash Then
'Data was corrupted
Throw New ArgumentException("Hash value does not match")
'This error is immediately caught below
End If
Catch ex As Exception
Throw New ArgumentException("Invalid TamperProofString")
End Try


Return dataValue

End Function

Calling the Encoding function for a hyperlink control given below:

HyperLink1.NavigateUrl = "Mypage.aspx?UId=" & TamperProofStringEncode("Put your UserId here", "Put your secret key here")

For example:

HyperLink1.NavigateUrl = "Mypage.aspx?UId=" & TamperProofStringEncode("12", "XALM123")

In the receiving page:

int UserId = TamperProofStringDecode(Request.QueryString["UId"], "XALM123").ToString()

Note: In the Decrypting function we have used .Replace(" ", "+")

This is because, sometimes the Encoded string may contain the plus sign (+) which is passed in the query string as “”. In the receiving page, the Decoding function try to decode the query string that do not have the plus (+) sign. Then an error ‘Invalid length for a Base-64 char array‘ will occur.
To avoid this error, we need to use the Replace function, Replace(" ", "+").