Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

C# Save and Load Image from Database

0.00/5 (No votes)
5 Mar 2009 1  
Save images to database and load in aspx page using C#

Introduction

This article shows you how to upload an image in a C# application, save it in a database and display it in another aspx page.

Background

HTML img tag and Image control in C# always look for an image on the hard disk or some physical location on a server. This article shows how to overcome that by specifying the image source as another aspx file which returns an image.

It may not be feasible to store all the images on the hard disk and index them. It also takes more time to read and write to a hard disk. So, storing the images in database is the way to go if your application uses more images in a dynamic page.

This article shows how to display dynamic images from database, how to convert image to bytearray and how to use generic handlers.

Using the Code

First the uploaded image must be saved in the database.

Image Upload

Upload functionality can be implemented easily by using the Fileupload control and a submit button in the upload page.

<asp:FileUpload runat="server" ID="flImage" />
<asp:Button runat="server" ValidationGroup="Details" ID="btnSubmit" Text="Upload"
    onclick="btnSubmit_Click" />

The selected image from the fileupload control must be stored in the msg table. Let us assume the msg table has two fields:

Table Name: msg

Field Name Data Type Primary Key Nullable
msgid int Yes No
pic1 blob No Yes

Have the msgid as an autoincrement field if required so that it may not be required to be updated.

On the submit button click event, insert a record in msg table.

The selected image must be converted to a byte array before being inserted into the table.

private byte[] ConvertImageToByteArray(System.Drawing.Image imageToConvert,
                                       System.Drawing.Imaging.ImageFormat formatOfImage)
{
    byte[] Ret;
    try
    {
        using (MemoryStream ms = new MemoryStream())
        {
            imageToConvert.Save(ms, formatOfImage);
            Ret = ms.ToArray();
        }
    }
    catch (Exception) { throw; }
    return Ret;
}

On the submit button click event, get the selected image in the Image object by calling...

System.Drawing.Image.FromStream(flImage.PostedFile.InputStream) 

... and store it in the image object. This image object must be converted to a byte array to be able to store in a blob field. This is done by calling the above ConvertImageToByteArray() function.

Now setup the database connection in the button click event and update the msg table's pic1 field with the bytearray that we got from the ConvertImageToByteArray() function.

//Upload image to database
protected void btnSubmit_Click(object sender, EventArgs e)
{
    System.Drawing.Image imag = System.Drawing.Image.FromStream(
        flImage.PostedFile.InputStream);
    System.Data.SqlClient.SqlConnection conn = null;
    try
    {
        try
        {
            conn = new System.Data.SqlClient.SqlConnection(
                ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString);
            conn.Open();
            System.Data.SqlClient.SqlCommand insertCommand =
                new System.Data.SqlClient.SqlCommand(
                "Insert into [msg] (msgid, pic1) Values (1, @Pic)", conn);
            insertCommand.Parameters.Add("Pic", SqlDbType.Image, 0).Value =
                ConvertImageToByteArray(imag, System.Drawing.Imaging.ImageFormat.Jpeg);
            int queryResult = insertCommand.ExecuteNonQuery();
            if (queryResult == 1)
                lblRes.Text = "msg record Created Successfully";
        }
        catch (Exception ex)
        {
            lblRes.Text = "Error: " + ex.Message;
        }
    }
    finally
    {
        if (conn != null)
            conn.Close();
    }
}

Generic Handler to Display Image

As we know, the aspx image control looks for a physical location of an Image file in its ImageUrl attribute. The trick is to specify another dedicated handler file which will act as an image. This handler (ImgHandler.ashx) will not have any HTML decoration since we are not displaying this page separately, instead it will act as an image. To do that, its ProcessRequest event must be modified to read the image from the database and return the image as the response.

Calling Response.BinaryWrite() function from the ProcessRequest event will make this ashx handler as an image by the calling aspx page.

public void ProcessRequest (HttpContext context)
{
        System.Data.SqlClient.SqlDataReader rdr = null;
        System.Data.SqlClient.SqlConnection conn = null;
        System.Data.SqlClient.SqlCommand selcmd = null;
        try
        {
          conn = new System.Data.SqlClient.SqlConnection
		(System.Configuration.ConfigurationManager.ConnectionStrings
		["ConnectionString"].ConnectionString);
          selcmd = new System.Data.SqlClient.SqlCommand
		("select pic1 from msg where msgid=" + 
		context.Request.QueryString["imgid"], conn);
          conn.Open();
          rdr = selcmd.ExecuteReader();
          while (rdr.Read())
          {
            context.Response.ContentType = "image/jpg";
            context.Response.BinaryWrite((byte[])rdr["pic1"]);
          }
          if (rdr != null)
            rdr.Close();
        }
        finally
        {
          if (conn != null)
              conn.Close();
        }
}

In the above code, notice that the ProcessRequest event opens the database and loads the image with the image id matching the image id sent from the request query string.

This code only saves and retrieves images in JPG format. Although other image formats like GIF, PNG, BMP, etc. will work with the same code, the image quality will not be maintained if all other image formats are read as JPG formats. This code must be updated to handle different image formats while writing to database and setting the content type in the response.

Display the Image

Now this can be accessed from any aspx page by setting the ImageUrl to the above handler.

  <asp:Image ID="picone" ImageUrl="ImgHandler.ashx?imgid=1" runat="server" />

imgid is sent as a querystring to ImgHandler.ashx in order to fetch the right image from the database and display it.

Points of Interest

Image control in C# expects ImageUrl which is a physical image in the server. This article shows the workaround of making an ashx handler behave like a physical image. It also presents all the related code behind saving and retrieving image to and from database. This article shows database access in plain SQL in code for quick understanding. These SQL statements must be protected to prevent from SQL injection by hackers.

Happy coding!

History

  • 13th February, 2009: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here