Meet us at PRINT 19. Chicago, IL. Oct. 3 - 5.
This documentation is for the old version. Go to the latest Graphics Mill docs

Loading and Saving Images to Database

No doubt, that images are very important part of content of any site. The essential question is what is the best way to store the images to provide easier access, reduce overheads, protect them from illegal copying and so on. Generally the pictures are stored as image files on the hard drive. However there is an alternative way: to store them in the database as BLOB fields. Using database is rather wide-spread practice in web development. It is difficult to say what way is better, it depends on many factors. Anyway, Graphics Mill for .NET allows to work both with files and database fields. This article describes how Graphics Mill for .NET can be used to work with database. If you more interested in working with files, you can read this article.

First of all, if you store images in format which are compliant with web-browsers (for example, JPEG) and you need not make any changes in the image, it is possible you should not use Graphics Mill for .NET at all and retrieve image directly from database to browser. It will reduce server burden and will help to avoid quality loss (if you deal with JPEG). However there are common situations when image format stored in database is not supported by browsers (for example TIFF) or you need to display web-optimized version of image. In this case Graphics Mill for .NET provides all necessary means.

Let's begin with loading image from database. This code example is written for SQL Server database. An example for Access (through OLE DB) can be found below.

The idea is a following: put the content of the BLOB field into binary array. After that create System.IO.MemoryStream class instance that uses this array, and pass this stream into Load method of the Bitmap class. Draw attention, constructor of the System.IO.MemoryStream constructor does not copy this array, but works with it directly. That's why using this class does not cause memory overhead.

Visual Basic
Dim connection As New System.Data.SqlClient.SqlConnection(connectionString)
Dim command As New System.Data.SqlClient.SqlCommand( _
 "SELECT Image_Data FROM [Image] WHERE Image_ID=" & imageID, connection)

connection.Open()
Dim imageData As Byte() = command.ExecuteScalar()
connection.Close()

Dim stream As New System.IO.MemoryStream(imageData)

Dim bitmap As New Aurigma.GraphicsMill.Bitmap(stream)
C#
System.Data.SqlClient.SqlConnection connection =
    new System.Data.SqlClient.SqlConnection(connectionString);
System.Data.SqlClient.SqlCommand command =
    new System.Data.SqlClient.SqlCommand("SELECT Image_Data FROM [Image] WHERE Image_ID=" +
    imageID, connection);

connection.Open();
byte[] imageData = (byte[])command.ExecuteScalar();
connection.Close();

System.IO.MemoryStream stream = new System.IO.MemoryStream(imageData);

Aurigma.GraphicsMill.Bitmap bitmap = new Aurigma.GraphicsMill.Bitmap(stream);

Now let's see how to save image into database. The idea is to do contrariwise: first we save data into System.IO.MemoryStream using Save method of the Bitmap class, get an internal array of bytes (i.e. without copying all data) using GetBuffer method of the System.IO.MemoryStream, and put this array into the BLOB field. Here is a code which demonstrates that:

Visual Basic
Dim bitmap As New Aurigma.GraphicsMill.Bitmap("c:\mountain.jpg")

'Resize bitmap
bitmap.Transforms.Resize(bitmap.Width \ 2, 0)

Dim connection As New System.Data.SqlClient.SqlConnection(connectionString)
Dim command As New System.Data.SqlClient.SqlCommand( _
 "INSERT INTO [Image](Image_Data) VALUES (@Image_Data)", connection)

Dim stream As New System.IO.MemoryStream
bitmap.Save(stream, New Aurigma.GraphicsMill.Codecs.JpegEncoderOptions(70, False))
Dim imageData As Byte() = stream.GetBuffer()

Dim parameter As New System.Data.SqlClient.SqlParameter("@Image_Data", _
 System.Data.SqlDbType.Image, imageData.Length)
parameter.Value = imageData
command.Parameters.Add(parameter)

connection.Open()
command.ExecuteNonQuery()
connection.Close()
C#
Aurigma.GraphicsMill.Bitmap bitmap =
    new Aurigma.GraphicsMill.Bitmap(@"c:\mountain.jpg");

//Resize bitmap
bitmap.Transforms.Resize(bitmap.Width / 2, 0);

System.Data.SqlClient.SqlConnection connection =
    new System.Data.SqlClient.SqlConnection(connectionString);
System.Data.SqlClient.SqlCommand command =
    new System.Data.SqlClient.SqlCommand("INSERT INTO [Image](Image_Data) " +
    "VALUES (@Image_Data)", connection);

System.IO.MemoryStream stream = new System.IO.MemoryStream();
bitmap.Save(stream, new Aurigma.GraphicsMill.Codecs.JpegEncoderOptions(70, false));
byte[] imageData = stream.GetBuffer();

System.Data.SqlClient.SqlParameter parameter = new System.Data.SqlClient.SqlParameter(
    "@Image_Data", System.Data.SqlDbType.Image, imageData.Length);
parameter.Value = imageData;
command.Parameters.Add(parameter);

connection.Open();
command.ExecuteNonQuery();
connection.Close();

If you work with OLE DB, the code is almost the same. The same is true for ODBC. This code loads image from the database through OLE DB:

Visual Basic
Dim connection As New System.Data.OleDb.OleDbConnection(connectionString)
Dim command As New System.Data.OleDb.OleDbCommand( _
 "SELECT Image_Data FROM [Image] WHERE Image_ID=" & imageID, connection)

connection.Open()
Dim imageData As Byte() = command.ExecuteScalar()
connection.Close()

Dim stream As New System.IO.MemoryStream(imageData)

Dim bitmap As New Aurigma.GraphicsMill.Bitmap(stream)
C#
System.Data.OleDb.OleDbConnection connection =
    new System.Data.OleDb.OleDbConnection(connectionString);
System.Data.OleDb.OleDbCommand command =
    new System.Data.OleDb.OleDbCommand("SELECT Image_Data FROM [Image] WHERE Image_ID=" +
    imageID, connection);

connection.Open();
byte[] imageData = (byte[])command.ExecuteScalar();
connection.Close();

System.IO.MemoryStream stream = new System.IO.MemoryStream(imageData);

Aurigma.GraphicsMill.Bitmap bitmap = new Aurigma.GraphicsMill.Bitmap(stream);

This code demonstrates saving image into database using OLE DB:

Visual Basic
Dim bitmap As New Aurigma.GraphicsMill.Bitmap("c:\mountain.jpg")

'Resize bitmap
bitmap.Transforms.Resize(bitmap.Width \ 2, 0)

Dim connection As New System.Data.OleDb.OleDbConnection(connectionString)
Dim command As New System.Data.OleDb.OleDbCommand( _
 "INSERT INTO [Image](Image_Data) VALUES (?)", connection)

Dim stream As New System.IO.MemoryStream
bitmap.Save(stream, New Aurigma.GraphicsMill.Codecs.JpegEncoderOptions(70, False))
Dim imageData As Byte() = stream.GetBuffer()

Dim parameter As New System.Data.OleDb.OleDbParameter("@Image_Data", _
 System.Data.OleDb.OleDbType.LongVarBinary, imageData.Length)
parameter.Value = imageData
command.Parameters.Add(parameter)

connection.Open()
command.ExecuteNonQuery()
connection.Close()
C#
Aurigma.GraphicsMill.Bitmap bitmap =
    new Aurigma.GraphicsMill.Bitmap(@"c:\mountain.jpg");

//Resize bitmap
bitmap.Transforms.Resize(bitmap.Width / 2, 0);

System.Data.OleDb.OleDbConnection connection =
    new System.Data.OleDb.OleDbConnection(connectionString);
System.Data.OleDb.OleDbCommand command =
    new System.Data.OleDb.OleDbCommand("INSERT INTO [Image](Image_Data) " +
    "VALUES (?)", connection);

System.IO.MemoryStream stream = new System.IO.MemoryStream();
bitmap.Save(stream, new Aurigma.GraphicsMill.Codecs.JpegEncoderOptions(70, false));
byte[] imageData = stream.GetBuffer();

System.Data.OleDb.OleDbParameter parameter = new System.Data.OleDb.OleDbParameter(
    "@Image_Data", System.Data.OleDb.OleDbType.LongVarBinary, imageData.Length);
parameter.Value = imageData;
command.Parameters.Add(parameter);

connection.Open();
command.ExecuteNonQuery();
connection.Close();