C# Resize jpg image, convert to byte and save into database using varbinary

XiAnG picture XiAnG · Jun 27, 2013 · Viewed 12.5k times · Source

I'm trying to resize my jpg image uploaded by using FileUpload control and convert it into byte before saving it to database (SQL Server 2008) as (varbinary(MAX)). What I have done and code show below was that I manage to convert it into byte and save into database as varbinary(MAX). I wish to know how to I resize the image before doing all those function. Do help me out. Thanks!

Read the file

string filePath = FileUpload1.PostedFile.FileName;
string filename = Path.GetFileName(filePath);
string ext = Path.GetExtension(filename);

Set the contenttype based on File Extension

string contenttype = String.Empty;            
switch (ext)
{
   case ".jpg":
   contenttype = "image/jpg";
   break;
}

Convert into byte and save into database using varbinary

if (contenttype != String.Empty)
{
            Stream fs = FileUpload1.PostedFile.InputStream;

            BinaryReader br = new BinaryReader(fs);

            Byte[] bytes = br.ReadBytes((Int32)fs.Length);

            //insert the file into database
            string strQuery = "insert into MemberReport(username, typeofcrime, location, crdatetime, citizenreport, image1, image2, image3, image4, image5)" +
               " values ('" + username + "','" + typeofcrime + "','" + location.Trim() + "','" + datetime + "','" + detail.Trim() + "', @Data, @Data2, @Data3, @Data4, @Data5)";
            SqlCommand cmd = new SqlCommand(strQuery);
            cmd.Parameters.Add("@Data", SqlDbType.Binary).Value = bytes;
            cmd.Parameters.Add("@Data2", SqlDbType.Binary).Value = bytes2;
            cmd.Parameters.Add("@Data3", SqlDbType.Binary).Value = bytes3;
            cmd.Parameters.Add("@Data4", SqlDbType.Binary).Value = bytes4;
            cmd.Parameters.Add("@Data5", SqlDbType.Binary).Value = bytes5;
            InsertUpdateData(cmd);

            lblMessage.ForeColor = System.Drawing.Color.Green;
            lblMessage.Text = "Report Sent!";

        }
        else
        {
            lblMessage.ForeColor = System.Drawing.Color.Red;
            lblMessage.Text = "File format not recognised." +
              " Upload Image formats";
        }

InsertUpdateData method

    private Boolean InsertUpdateData(SqlCommand cmd)
    {
        SqlConnection con = new SqlConnection("Data Source=localhost; Initial Catalog=project; Integrated Security=True");
        cmd.CommandType = CommandType.Text;
        cmd.Connection = con;
        try
        {
            con.Open();
            cmd.ExecuteNonQuery();
            return true;
        }
        catch (Exception ex)
        {
            Response.Write(ex.Message);
            return false;
        }
        finally
        {
            con.Close();
            con.Dispose();
        }

Answer

Corey picture Corey · Jun 27, 2013

You need to convert the uploaded file to an Image object, which can be done simply with:

Image uploaded = Image.FromStream(FileUpload1.PostedFile.InputStream);

Next, figure out how big you want the image to be. Let's say you want the largest dimension to be 256 pixels, and maintain aspect ratio. Some code adapted from the CodeProject article Resizing an Image On-The-Fly using .NET:

int originalWidth = uploaded.Width;
int originalHeight = uploaded.Height;
float percentWidth = (float)256 / (float)originalWidth;
float percentHeight = (float)256 / (float)originalHeight;
float percent = percentHeight < percentWidth ? percentHeight : percentWidth;
int newWidth = (int)(originalWidth * percent);
int newHeight = (int)(originalHeight * percent);

Now create a new Bitmap object to contain the resized image (from the same CodeProject article) and draw the original image to it:

Image newImage = new Bitmap(newWidth, newHeight);
using (Graphics g = Graphics.FromImage(newImage))
{
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    g.DrawImage(uploaded, 0, 0, newWidth, newHeight);
}

And finally, convert back to bytes to save into the database:

byte[] results;
using (MemoryStream ms = new MemoryStream())
{
    ImageCodecInfo codec = ImageCodecInfo.GetImageEncoders().FirstOrDefault(c => c.FormatID == ImageFormat.Jpeg.Guid);
    EncoderParameters jpegParms = new EncoderParameters(1);
    jpegParms.Param[0] = new EncoderParameter(Encoder.Quality, 95L);
    newImage.Save(ms, codec, jpegParms);
    results = ms.ToArray();
}

I took the long route to set the quality level of the output. If you don't mind what compression level is used, a simple img.Save(ms, ImageFormat.Jpeg); call replaces the first 4 lines inside the using code block.

Check out the CodeProject article I mentioned above for more information on resizing images, and read C# Image to Byte Array and Byte Array To Image Converter Class (also on CodeProject) for more on converting images to/from byte arrays.


The last part, inserting the image into a database table. I'll assume Microsoft SQL, and do a very simple table insert.

Table is defined as:

CREATE TABLE [Images](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [ImageData] [varbinary](max) NULL,
    CONSTRAINT [PK_Images] PRIMARY KEY CLUSTERED 
    (
        [ID] ASC
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

And the code to insert the image data into the table:

static string connString = "Data Source=localhost; Initial Catalog=project; Integrated Security=True";

public static int InsertImage(byte[] imgdata)
{
    using (SqlConnection conn = new SqlConnection(connString))
    {
        conn.Open();

        using (SqlCommand cmd = new SqlCommand("INSERT INTO Images(ImageData) OUTPUT inserted.ID VALUES(@p1)", conn))
        {
            cmd.Parameters.AddWithValue("@p1", imgdata);

            int res = (int)cmd.ExecuteScalar()
            return res;
        }
    }
}

The returned value is the auto-increment value generated by SQL for the record.

Or to update an existing image:

public static void UpdateImage(int id, byte[] imgdata)
{
    using (SqlConnection conn = new SqlConnection(connString))
    {
        conn.Open();
        using (SqlCommand cmd = new SqlCommand("UPDATE Images SET ImageData = @p1 WHERE ID = @p2", conn))
        {
            cmd.Parameters.AddWithValue("@p1", imgdata);
            cmd.Parameters.AddWithValue("@p2", id);

            cmd.ExecuteNonQuery();
        }
    }
}