DCSIMG
Building the image engine - Wortzel's blog

Wortzel's blog

.Net (2.0, 3.0, 3.5), C#, Asp.net, Com+, GIS(ESRI Software), Management, Analysis & Design, Life, Trips, And more...
Building the image engine

In our project we had a dilemma if we should store image files in database or in file system directory.

There are some pros' and cons' for each option, but the most important issue that influenced our decision was that we work with ESRI tools. If the image is small it's better to store it in the file system and not in the database. If we store the image in database (using SDE), it will takes some time and this operation couldn't be in real-time reaction (because the SDE will create a pyramids and others statistics operations before the image is being stored in the database).

I want to share with you an example to insert and retrieve images that have been stored in the database in Image type (SQL server data type, from BLOB family).

 

Insert an image to database:

private void InsertImageToDatabaseColumn(int imageId)
{
   MemoryStream mem = new MemoryStream();
   byte[] imageData = new byte[1024];

   Stream imageStream = FileUpload1.PostedFile.InputStream;
   int imageLength = FileUpload1.PostedFile.ContentLength;
   string imageType = FileUpload1.PostedFile.ContentType;
   int count = 0;

   while (0 < (count = imageStream.Read(imageData, 0, imageData.Length)))
   {
      mem.Write(imageData, 0, count);
   }

   using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ToString()))
   {
      using (SqlCommand command = new SqlCommand())
      {
         command.Connection = conn;
         command.CommandText = "Insert into Images values (@Id,@Image)";
         SqlParameter p1 = new SqlParameter();
         p1.ParameterName = "Id";
         p1.Value = imageId;
         command.Parameters.Add(p1);
         p1 = new SqlParameter();
         p1.ParameterName = "Image";
         p1.Value = mem.GetBuffer();
         command.Parameters.Add(p1);
         conn.Open();
         command.ExecuteNonQuery();
      }
   }
}

Show an  image from database:

private void GetAndBindImageCoulmn(int imageId)
{
   byte[] imageBytes;
   using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ToString()))
   {
      using (SqlCommand command = new SqlCommand())
      {
         command.Connection = conn;
         command.CommandText = "Select image from Images where id = @ImageId ";
         SqlParameter parameter = new SqlParameter("ImageId", SqlDbType.Int);
         parameter.Value = imageId;
         command.Parameters.Add(parameter);
         conn.Open();
         using (SqlDataReader reader = command.ExecuteReader())
         {
            reader.Read();
            imageBytes = (byte[])reader.GetValue(0);
            MemoryStream tempStream = new MemoryStream(imageBytes, 0, imageBytes.Length);
            Bitmap bitmap = new Bitmap(tempStream);
            Response.ContentType = "image/gif";
            bitmap.Save(Response.OutputStream, ImageFormat.Gif);
            Response.End();
         }
      }
   }
}

 

Published Thursday, April 05, 2007 11:57 PM by Avi Wortzel

Comments

# re: Building the image engine - Summary of "Programming Microsoft ADO.NET 2.0 applications Advances topics" book – Part #5@ Sunday, April 08, 2007 6:05 PM

this is actually an old debate about images.

at first, it seems that the file system is the natural place of images.

but putting it in the DB may enhance the simplicity of implementing security issues such as authorized viewing,

although it can be implemented via file system too, saving the image as a blob can make our life easier.

about performance, there is a substantial performance hit, but some times it's inevitable.

Shimon krohkmal

# re: Building the image engine - Summary of "Programming Microsoft ADO.NET 2.0 applications Advances topics" book – Part #5@ Sunday, April 15, 2007 12:12 AM

Why you using the Bitmap class, you can read the bytes to the response with out use the bitmap.

Yoav Michaeli

# re: Building the image engine - Summary of "Programming Microsoft ADO.NET 2.0 applications Advances topics" book – Part #5@ Sunday, April 15, 2007 1:53 AM

Two Things you forgot to mention:

1) this sample can't retrieve data from  a geographic queries, because it is a pure data column not SDE-enabled.

2) This image has no coordinate system at all, so you are kind of loosing the Geo-Aspect.

But I truely loved the idea,

One more question:

Why won't you simply use a Raster catalog?

Shani.

rabashani

# re: Building the image engine - Summary of "Programming Microsoft ADO.NET 2.0 applications Advances topics" book – Part #5@ Monday, April 16, 2007 11:24 PM

Hi everyone, thank you for your comments.

Shimon – the performance subject is one of the important issues in our project, so we decided that we should prefer to take care of this problem, rather than the maintenance difficultly.

Yoav – You are right I could just implement it with the Response object without saving it to a file. But this is just an example of reading the image and there isn't a focus on how to show it.

Shani –

1) You are right, this solution isn't good for any product that manages images storing in its own format.

2) I can save the coordination system either in a world file or a prj file in order to save the correct coordination system of your image.

And about the raster catalog:

The main problems in raster catalog are:

- It can't hold rasters from different coordination system in the same raster catalog.

- A raster catalog that is based on file system can't hold a raster from the SDE.

Avi Wortzel