locked
C# Image resize RRS feed

  • Question

  • User1409068123 posted

    I know there has been alot of posting about image resizing but not too much info on code written in C#

    Does anyone have some good code for this in C#

     

    Monday, October 23, 2006 6:54 PM

All replies

  • User-1372641848 posted

    Try this How to calculate image size of uploaded image

    And Live sample  

    Monday, October 23, 2006 8:18 PM
  • User300685930 posted

    You are right, there is not much posted.  Let me change that.  Here is a routine I use.

     public static byte[] ResizeFromByteArray(string fileName, int MaxSideSize, Byte[] byteArrayIn)
            {
                byte[] byteArray = null;  // really make this an error gif
                MemoryStream ms = new MemoryStream(byteArrayIn);
                byteArray = CodeCampSV.Utils.ResizeFromStream(fileName, MaxSideSize, ms);



                return byteArray;
            }

            /// <summary>
            /// converts from input stream to output bytearray
            /// inspired from: http://www.eggheadcafe.com/articles/20030515.asp
            /// </summary>
            /// <param name="ImageSavePath"></param>
            /// <param name="MaxSideSize"></param>
            /// <param name="Buffer"></param>
            /// <returns></returns>
            public static byte[] ResizeFromStream(string fileName, int MaxSideSize, Stream Buffer)
            {
                byte[] byteArray = null;  // really make this an error gif

                try
                {

                    


                    Bitmap bitMap = new Bitmap(Buffer);
                    int intOldWidth = bitMap.Width;
                    int intOldHeight = bitMap.Height;

                    int intNewWidth;
                    int intNewHeight;

                    int intMaxSide;

                    if (intOldWidth >= intOldHeight)
                    {
                        intMaxSide = intOldWidth;
                    }
                    else
                    {
                        intMaxSide = intOldHeight;
                    }

                    if (intMaxSide > MaxSideSize)
                    {
                        //set new width and height
                        double dblCoef = MaxSideSize / (double)intMaxSide;
                        intNewWidth = Convert.ToInt32(dblCoef * intOldWidth);
                        intNewHeight = Convert.ToInt32(dblCoef * intOldHeight);
                    }
                    else
                    {
                        intNewWidth = intOldWidth;
                        intNewHeight = intOldHeight;
                    }

                    Size ThumbNailSize = new Size(intNewWidth, intNewHeight);
                    System.Drawing.Image oImg = System.Drawing.Image.FromStream(Buffer);
                    System.Drawing.Image oThumbNail = new Bitmap
                        (ThumbNailSize.Width, ThumbNailSize.Height);
                    Graphics oGraphic = Graphics.FromImage(oThumbNail);
                    oGraphic.CompositingQuality = CompositingQuality.HighQuality;
                    oGraphic.SmoothingMode = SmoothingMode.HighQuality;
                    oGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    Rectangle oRectangle = new Rectangle
                        (0, 0, ThumbNailSize.Width, ThumbNailSize.Height);

                    oGraphic.DrawImage(oImg, oRectangle);

                    //string fileName = Context.Server.MapPath("~/App_Data/") + "test1.jpg";
                    //oThumbNail.Save(fileName, ImageFormat.Jpeg);
                    MemoryStream ms = new MemoryStream();
                    oThumbNail.Save(ms, ImageFormat.Jpeg);
                    byteArray = new byte[ms.Length];
                    ms.Position = 0;
                    ms.Read(byteArray, 0, Convert.ToInt32(ms.Length));

                    oGraphic.Dispose();
                    oImg.Dispose();
                    ms.Close();
                    ms.Dispose();
                }
                catch (Exception)
                {
                    int newSize = MaxSideSize - 20;
                    Bitmap bitMap = new Bitmap(newSize, newSize);
                    Graphics g = Graphics.FromImage(bitMap);
                    g.FillRectangle(new SolidBrush(Color.Gray), new Rectangle(0, 0, newSize, newSize));

                    Font font = new Font("Courier", 8);
                    SolidBrush solidBrush = new SolidBrush(Color.Red);
                    g.DrawString("Failed File", font, solidBrush, 10, 5);
                    g.DrawString(fileName, font, solidBrush, 10, 50);

                    MemoryStream ms = new MemoryStream();
                    bitMap.Save(ms, ImageFormat.Jpeg);
                    byteArray = new byte[ms.Length];
                    ms.Position = 0;
                    ms.Read(byteArray, 0, Convert.ToInt32(ms.Length));

                    ms.Close();
                    ms.Dispose();
                    bitMap.Dispose();
                    solidBrush.Dispose();
                    g.Dispose();
                    font.Dispose();

                }
                return byteArray;
            }

    Monday, October 23, 2006 8:40 PM
  • User1409068123 posted

    Should I assume that in order to run this I would have some code that looks something like

     ResizeFromStream("c:\\img\\filename.jpg", "500")

    Also does this only work for jpg's or does it work for all image types?

    Monday, October 23, 2006 10:11 PM
  • User300685930 posted
    take a look at the MapPath below.  Also the type is based on: Bitmap bitMap = new Bitmap(Buffer);  Whatever Bitmap takes.
    Monday, October 23, 2006 10:47 PM
  • User1409068123 posted

    I am sorry I am extremely new to C# I took classes in C++ about 6 years ago but ever since I have only been working in ASP Classic

     Please give an example of how to call this code

     

    Monday, October 23, 2006 10:59 PM
  • User300685930 posted

    Not sure this is that helpful if you're new to c#, but this is the handler I wrote for displaying an image from a database.

    <%@ WebHandler Language="C#" Class="DisplayImage" %>

    using System;
    using System.Web;

    public class DisplayImage : IHttpHandler {
       
        public void ProcessRequest (HttpContext context) {

            System.Data.SqlTypes.SqlBytes imageArray = null;
            byte[] byteArray = null;
           
            try
            {
                string strParamHorizontalSize = context.Request.QueryString["sizex"];
                string strParam1 = context.Request.QueryString["pkid"];
                string strParam2 = context.Request.QueryString["roomid"];
                string strParam3 = context.Request.QueryString["pictureid"];
                if (!String.IsNullOrEmpty(strParam1) ||
                    !String.IsNullOrEmpty(strParam2) ||
                    !String.IsNullOrEmpty(strParam3))
                {

                    int paramHorizontalSize = 0;
                    Int32.TryParse(strParamHorizontalSize, out paramHorizontalSize);
                       
                    string paramString = context.Request.RawUrl.Substring(context.Request.RawUrl.IndexOf('?')+1);
                   
                    string cacheName = string.Empty;
                    if (!String.IsNullOrEmpty(strParam1))
                    {
                        cacheName = CodeCampSV.Utils.CacheDisplayImage + "?pkid=" + strParam1 + "&sizex=" + paramHorizontalSize.ToString();
                    }
                    else if (!String.IsNullOrEmpty(strParam2))
                    {
                        cacheName = CodeCampSV.Utils.CacheDisplayImage + "?roomid=" + strParam2 + "&sizex=" + paramHorizontalSize.ToString();
                    }
                    else if (!String.IsNullOrEmpty(strParam3))
                    {
                        cacheName = CodeCampSV.Utils.CacheDisplayImage + "?pictureid=" + strParam3 + "&sizex=" + paramHorizontalSize.ToString();
                    }

                    if (HttpContext.Current.Cache[cacheName] == null)
                    {
                        System.Data.SqlClient.SqlConnection sqlConnection =
                            new System.Data.SqlClient.SqlConnection
                            (System.Configuration.ConfigurationManager.ConnectionStrings["CodeCampSV06"].ConnectionString);
                        sqlConnection.Open();

                        string sqlSelect = string.Empty;
                        if (!String.IsNullOrEmpty(strParam1))
                        {
                            sqlSelect = "SELECT UserImage FROM attendees WHERE PKID=@PKID";
                        }

                        if (!String.IsNullOrEmpty(strParam2))
                        {
                            sqlSelect = "SELECT picture FROM LectureRooms WHERE id=@id";
                        }

                        if (!String.IsNullOrEmpty(strParam3))
                        {
                            sqlSelect = "SELECT PictureBytes FROM Pictures WHERE id=@id";
                        }

                        System.Data.SqlClient.SqlCommand sqlCommand = new System.Data.SqlClient.SqlCommand(
                            sqlSelect, sqlConnection);

                        if (!String.IsNullOrEmpty(strParam1))
                        {
                            Guid userGuid = new Guid(strParam1);
                            sqlCommand.Parameters.Add("@PKID", System.Data.SqlDbType.UniqueIdentifier).Value = userGuid;
                        }





                        if (!String.IsNullOrEmpty(strParam2))
                        {
                            int roomId = 0;
                            Int32.TryParse(strParam2, out roomId);
                            sqlCommand.Parameters.Add("@id", System.Data.SqlDbType.Int).Value = roomId;
                        }

                        if (!String.IsNullOrEmpty(strParam3))
                        {
                            int pictureId = 0;
                            Int32.TryParse(strParam3, out pictureId);
                            sqlCommand.Parameters.Add("@id", System.Data.SqlDbType.Int).Value = pictureId;
                        }

                        System.Data.SqlClient.SqlDataReader sqlDataReader = null;

                        sqlDataReader = sqlCommand.ExecuteReader();

                        while (sqlDataReader.Read())
                        {
                            if (!sqlDataReader.IsDBNull(0))
                            {
                                imageArray = sqlDataReader.GetSqlBytes(0);
                                byteArray = new byte[imageArray.Length];
                                imageArray.Read(0, byteArray, 0, Convert.ToInt32(imageArray.Length));
                            }
                            else
                            {
                                byteArray = GetEmptyImagePicture();
                            }
                        }
                        sqlDataReader.Close();
                        sqlDataReader.Dispose();
                        sqlConnection.Close();
                        sqlConnection.Dispose();
                        if (!String.IsNullOrEmpty(cacheName) && byteArray != null)
                        {
                            HttpContext.Current.Cache.Insert(cacheName, byteArray,
                            null, DateTime.Now.Add(new TimeSpan(0, 5, 0)), TimeSpan.Zero);
                        }
                        else
                        {
                        }
                    }
                    else
                    {
                        byteArray = (byte[])HttpContext.Current.Cache[cacheName];
                    }

                    context.Response.ContentType = "image/jpg";

                    if (paramHorizontalSize != 0)
                    {
                        byte[] ba = CodeCampSV.Utils.ResizeFromByteArray(string.Empty, paramHorizontalSize, byteArray);
                        if (byteArray != null)
                        {
                            context.Response.BinaryWrite(ba);
                        }
                    }
                    else
                    {
                        if (byteArray != null)
                        {
                            context.Response.BinaryWrite(byteArray);
                        }
                    }
                    //context.Response.End();
                   
                }
            }
            catch (Exception eee)
            {
                string er = eee.ToString();
                throw new ApplicationException(eee.ToString());
            }
            finally
            {
               
            }

            //context.Response.ContentType = "image/jpg";
            //context.Response.BinaryWrite(byteArray);
            //context.Response.End();
        }
     
     

        private byte[] GetEmptyImagePicture()
        {
            string nopicFilename = HttpContext.Current.Server.MapPath("~/Images/") + "nopic.gif";
            System.Drawing.Bitmap bitMap = new System.Drawing.Bitmap(nopicFilename);
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            bitMap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            byte[] byteArray = new byte[ms.Length];
            ms.Position = 0;
            ms.Read(byteArray, 0, Convert.ToInt32(ms.Length));
            ms.Close();
            ms.Dispose();
            bitMap.Dispose();
            return byteArray;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }



    Monday, October 23, 2006 11:05 PM
  • User1409068123 posted

    I appreciate your assistence in this I know it can be a bit annoying helping out a person that is getting their start in a new language.

    That being said to try to put my project into perspective here is what I am trying to accomplish and some of my current code I have.

     As my first project with C# ASP.NET 2K5

    I am building a clone if you will of imageshack or Photobucket

    Currently you can take a look at what a week into this project (along with doing my normal job of Classic ASP to keep money coming in) has gotten me http://shotdrive.com

     

    I have a Gridview that has a TemplateField which shows the uploaded images. These images are not saved to the Database for planning of what the future would bring in a real life scenerio I would assume that if this were a site that would have thousands of users uploading a god awful amount of photos it would increase the size of the Database to an incredible amount. So I save the images to a folder "img" inside that folder each of the users have their own folder. Each user folder is named with the same GUID that is in the database for the userid (I know that is not the smartest naming concept in regards to security but it works for now.)

    So currently the images do show up in the gridview but they are a bit distorted. here is the code for the Gridview

    <asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True"

    AutoGenerateColumns="False" CellPadding="4" DataSourceID="SqlDataSource1" ForeColor="#333333"

    GridLines="None" Style="z-index: 103; left: 160px; ; top: 204px" OnSelectedIndexChanged="GridView1_SelectedIndexChanged">

    <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />

    <Columns>

    <asp:BoundField DataField="filename" HeaderText="filename" SortExpression="filename" />

    <asp:TemplateField HeaderText="Image">

    <ItemTemplate>

    <img src='img/<%# Eval("Directory")%>/<%# Eval("filename") %>'Height="70px" Width="70px"/>

    </ItemTemplate>

    </asp:TemplateField>

    </Columns>

    <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />

    <EditRowStyle BackColor="#999999" />

    <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />

    <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />

    <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />

    <AlternatingRowStyle BackColor="White" ForeColor="#284775" />

    </asp:GridView>

     You'll notice were I set the TemplateField for this to display the images

    <asp:TemplateField HeaderText="Image">

    <ItemTemplate>

    <img src='img/<%# Eval("Directory")%>/<%# Eval("filename") %>'Height="70px" Width="70px"/>

    </ItemTemplate>

    </asp:TemplateField>

    Alright now where I would like for this project to take me as to learn many of the aspects of this extremely flexible and powerful language.

    1) Ability to preview the images as thumbnails in the gridview so that they are not distorted looking.

    2) Ability to Click the image itself and have either another window open displaying the full view of the image or just a larger preview popping out to the side of or to the top of the Gridview (second one I understand would be a quit a bit more difficult and I would probably wait till I can start looking into AJAX for that.)

    When the File is uploaded have the user presented with the option of resizing it but it is over say 600X800 force the user to resize it to a lower size. Store the original size in the database. I say store the original size in the database because I am assuming that when you change the size of the file you are not changing the DPI meaning you can stretch it back to the original size without degrading it.

    Of course there are quit a lot of other things out there that I think would not only be nice features to have on the site but also allow me more learning room.

    Eventually I would like to get into learning how to build my own DLL files so that ( like someone else suggested to me) I could build my own libraries....

    Ok I understand that this may be a bit more then what this question started out with but thats what I get for trying to learn a new language, fight with my Networking crew, perform my regular programming work, and attempt to talk with the girlfriend and keep her happy.......[:D]

    Tuesday, October 24, 2006 12:45 AM
  • User1409068123 posted

    I appreciate your assistence in this I know it can be a bit annoying helping out a person that is getting their start in a new language.

    That being said to try to put my project into perspective here is what I am trying to accomplish and some of my current code I have.

     As my first project with C# ASP.NET 2K5

    I am building a clone if you will of imageshack or Photobucket

    Currently you can take a look at what a week into this project (along with doing my normal job of Classic ASP to keep money coming in) has gotten me http://shotdrive.com

     

    I have a Gridview that has a TemplateField which shows the uploaded images. These images are not saved to the Database for planning of what the future would bring in a real life scenerio I would assume that if this were a site that would have thousands of users uploading a god awful amount of photos it would increase the size of the Database to an incredible amount. So I save the images to a folder "img" inside that folder each of the users have their own folder. Each user folder is named with the same GUID that is in the database for the userid (I know that is not the smartest naming concept in regards to security but it works for now.)

    So currently the images do show up in the gridview but they are a bit distorted. here is the code for the Gridview

    <asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True"

    AutoGenerateColumns="False" CellPadding="4" DataSourceID="SqlDataSource1" ForeColor="#333333"

    GridLines="None" Style="z-index: 103; left: 160px; ; top: 204px" OnSelectedIndexChanged="GridView1_SelectedIndexChanged">

    <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />

    <Columns>

    <asp:BoundField DataField="filename" HeaderText="filename" SortExpression="filename" />

    <asp:TemplateField HeaderText="Image">

    <ItemTemplate>

    <img src='img/<%# Eval("Directory")%>/<%# Eval("filename") %>'Height="70px" Width="70px"/>

    </ItemTemplate>

    </asp:TemplateField>

    </Columns>

    <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />

    <EditRowStyle BackColor="#999999" />

    <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />

    <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />

    <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />

    <AlternatingRowStyle BackColor="White" ForeColor="#284775" />

    </asp:GridView>

     You'll notice were I set the TemplateField for this to display the images

    <asp:TemplateField HeaderText="Image">

    <ItemTemplate>

    <img src='img/<%# Eval("Directory")%>/<%# Eval("filename") %>'Height="70px" Width="70px"/>

    </ItemTemplate>

    </asp:TemplateField>

    Alright now where I would like for this project to take me as to learn many of the aspects of this extremely flexible and powerful language.

    1) Ability to preview the images as thumbnails in the gridview so that they are not distorted looking.

    2) Ability to Click the image itself and have either another window open displaying the full view of the image or just a larger preview popping out to the side of or to the top of the Gridview (second one I understand would be a quit a bit more difficult and I would probably wait till I can start looking into AJAX for that.)

    When the File is uploaded have the user presented with the option of resizing it but it is over say 600X800 force the user to resize it to a lower size. Store the original size in the database. I say store the original size in the database because I am assuming that when you change the size of the file you are not changing the DPI meaning you can stretch it back to the original size without degrading it.

    Of course there are quit a lot of other things out there that I think would not only be nice features to have on the site but also allow me more learning room.

    Eventually I would like to get into learning how to build my own DLL files so that ( like someone else suggested to me) I could build my own libraries....

    Ok I understand that this may be a bit more then what this question started out with but thats what I get for trying to learn a new language, fight with my Networking crew, perform my regular programming work, and attempt to talk with the girlfriend and keep her happy.......[:D]

    Tuesday, October 24, 2006 12:45 AM
  • User300685930 posted

    You are on the right track.  I'll cut and paste some more code showing how to use the image handler I pasted above.  I'd suggest using the <asp:Image> server control rather than the <img tagg.  gives you more options.  The important thing to look at is the "~/DisplayImage.ashx?sizex=150 in the code below.  That does the scaling.

     To see this in action, take a look at the code camp web site I put together.  Here is the URL.

    http://www.siliconvalley-codecamp.com/Sessions.aspx
     

     

     

    <div style='float: right;' runat='server' Visible='<%# (bool) GetHideSessionDescription() %>'>
                                    <asp:Image runat="server" ID="ImagePictureForSession" Visible='<%# (bool) IsPictureForSessionVisible() %>'
                                        ImageUrl='<%# "~/DisplayImage.ashx?sizex=150&" + GetDisplayImageURLForSessionPicture((int) Eval("id"),(int) Eval("LectureRoomsId"))  %>' />
                                    <%--<asp:Image runat="server" ID="ImageRoom" ImageUrl='<%# "~/DisplayImage.ashx?roomid=" + Eval("LectureRoomsId")  %>'
                                Visible='<%# (bool) IsRoomImageVisible() %>' />
                            <asp:Image runat="server" ID="ImagePicture" ImageUrl='<%# "~/DisplayImage.ashx?pictureid=" + (string) GetSessionPictureIdForSession((int) Eval("id"))  %>'
                                Visible='<%# (bool) IsSessionPicturesVisible() %>' />--%>
                                </div>

     

    Tuesday, October 24, 2006 12:59 AM
  • User1409068123 posted

    Alright I think I have alot to chew on for right now. I am going to spend the rest of the night attempting to make money in what I am now really starting to not like Classic ASP and then tomorrow I am going to jump back onto working on this because I am actually starting to enjoy programming again.

    I know it sounds cheesy but I truly was thinking about going back managing a tech support call center due to the enjoyment of programming has been drained from me. But learning C# it has put a new life back into it for me.....

     

    Dare I say It

    Thank you Microsoft for this new (fun!?????) yet powerful language

    Tuesday, October 24, 2006 1:14 AM