locked
Resizing Images When Uploaded RRS feed

  • Question

  • User1952191856 posted

    I fount this magnificent code by Kevin Jones to resize an image on the forum here.  I've messed around with it but its not doing what I want it to do.

    I need to create 3 images based on the image that was uploaded.

    One is a thumbnail, 80 x 80, which I don't have a problem creating.

    The second is a image for display, which would be 240 x 320 or 320 x 240.    I would like to do it where if the image that comes in is 1280 x 1024 then the new resized image should be 320 x 240 and if the image that comes in is 1024 x 1280 the new image is 240 x 320.

    Then a third, which does the same thing as above, but 480 x 640 or 640 x 480.

      

    string FileToResize = Server.MapPath("~/images/1.jpg");

    using(Bitmap originalBitmap = Bitmap.FromFile(FileToResize, true) as Bitmap, newbmp = new Bitmap(80,80))

    {

    double WidthVsHeightRatio = (float)originalBitmap.Width / (float)originalBitmap.Height;

    using(Graphics newg = Graphics.FromImage(newbmp))

    {

    newg.Clear(Color.White); newg.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

    if(WidthVsHeightRatio == 1d)

    {

    newg.DrawImage(originalBitmap, 0, 0, 80, 80);

    newg.Save();

    }

    else if(WidthVsHeightRatio < 1d) //Image is taller than wider

    {

    newg.DrawImage(originalBitmap, new RectangleF(new PointF((float)(40 - ((80 * WidthVsHeightRatio) / 2)), 0), new SizeF((float)(80 * WidthVsHeightRatio), 80f)));

    newg.Save();

    }

    else //Image is wider than taller

    {

    double inverse = Math.Pow(WidthVsHeightRatio, -1);

    newg.DrawImage(originalBitmap, new RectangleF(new PointF(0, (float)(40 - ((80 * inverse) / 2))), new SizeF(80f, (float)(80 * inverse))));

    newg.Save();

    }

    }

    newbmp.Save(Server.MapPath("~/images/1_resized.jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);

    }

    This is a little complicating, but here is the advantage to it: The output image is always 100 x 100, however the image keeps it's aspect ratio and centers the image in the middle of the 100 x 100 drawing.

    Tuesday, September 19, 2006 10:43 AM

Answers

  • User1439985827 posted
    Hm, my code sample doesn't handle non-square output unfortunately. Give me a while and after work I will post something that does that later this evening.
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, September 19, 2006 1:01 PM
  • User1439985827 posted
    Here is what I did. I made a function where you pass the file's path, where you want it to save the new one, then the new size you want. It will still function like the old one I wrote, but it will also do what you are looking for currently: 
    public void ResizePicture(string originalpath, string newpath, Size newsize)
    {
    	using (Bitmap newbmp = new Bitmap(newsize.Width, newsize.Height), oldbmp = Bitmap.FromFile(originalpath) as Bitmap)
    	{
    		using (Graphics newgraphics = Graphics.FromImage(newbmp))
    		{
    			newgraphics.Clear(Color.FromArgb(-1));
    			if ((float)oldbmp.Width / (float)newsize.Width == (float)oldbmp.Height / (float)newsize.Height) //Target size has a 1:1 aspect ratio
    			{
    				newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height);
    			}
    
    			else if ((float)oldbmp.Width / (float)newsize.Width > (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the top and bottom
    			{
    				newgraphics.DrawImage(oldbmp, 0f, (float)newbmp.Height / 2f - (oldbmp.Height * ((float)newbmp.Width / (float)oldbmp.Width)) / 2f, (float)newbmp.Width, oldbmp.Height * ((float)newbmp.Width / (float)oldbmp.Width));
    			}
    
    			else if ((float)oldbmp.Width / (float)newsize.Width < (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the sides
    			{
    				newgraphics.DrawImage(oldbmp, (float)newbmp.Width / 2f - (oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height)) / 2f, 0f, oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height), (float)newbmp.Height);
    			}
    
    			newgraphics.Save();
    			newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg);
    		}
    	}
    }
     a VB.NET version of it will be coming shortly for those that are interested.
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, September 19, 2006 11:33 PM
  • User1727473813 posted

    Nice, anychance you can go 1.1. vb....thanks

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 20, 2006 8:16 AM
  • User1727473813 posted

    Imports System.Drawing
    Imports System.Drawing.Imaging
    Imports System.Drawing.Drawing2D
    Imports System.Web
    Imports System.Web.UI
    Imports System.Web.UI.WebControls
    Imports System.Web.UI.HtmlControls

    Function UploadFile(ByVal strFile, ByVal strFileType, ByVal intRestarauntID)

     Dim strFileName As String = strFile.PostedFile.FileName
    ' Let us recover only the file name from its fully qualified path at client

    Dim c As String = System.IO.Path.GetFileName(strFileName)

    Dim strLocationOfNewFile = "C:\Inetpub\wwwroot\WebSite\Documents\" & c

    Dim NewSize = 100

    ResizePicture(strLocationOfNewFile, strLocationOfNewFile, NewSize)

    End Function

    ''Getting an issue on this line....Dim newbmp As New Bitmap

    Sub ResizePicture(ByRef originalpath As String, ByRef newpath As String, ByVal newsize As Size)

    Dim newbmp As New Bitmap(newsize.Width, newsize.Height), oldbmp As Bitmap = CType(Bitmap.FromFile(originalpath), Image)

    Dim newgraphics As Graphics = Graphics.FromImage(newbmp)

    newgraphics.Clear(Color.FromArgb(-1))

    If CSng(oldbmp.Width) / CSng(newsize.Width) = CSng(oldbmp.Height) / CSng(newsize.Height) Then

    newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height)

    ElseIf CSng(oldbmp.Width) / CSng(newsize.Width) > CSng(oldbmp.Height) / CSng(newsize.Height) Then

    newgraphics.DrawImage(oldbmp, 0.0F, CSng(newbmp.Height) / 2.0F - (oldbmp.Height * (CSng(newbmp.Width) / CSng(oldbmp.Width))) / 2.0F, CSng(newbmp.Width), oldbmp.Height * (CSng(newbmp.Width) / CSng(oldbmp.Width)))

    ElseIf CSng(oldbmp.Width) / CSng(newsize.Width) < CSng(oldbmp.Height) / CSng(newsize.Height) Then

    newgraphics.DrawImage(oldbmp, CSng(newbmp.Width) / 2.0F - (oldbmp.Width * (CSng(newbmp.Height) / CSng(oldbmp.Height))) / 2.0F, 0.0F, oldbmp.Width * (CSng(newbmp.Height) / CSng(oldbmp.Height)), CSng(newbmp.Height))

    End If

    newgraphics.Save()

    newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg)

    newgraphics.Dispose()

    oldbmp.Dispose()

    newbmp.Dispose()

    End Sub

    ERROR I GET... 

    c:\inetpub\wwwroot\\WebSite\BAL\CommonFunctions.vb(177): 'Image' is ambiguous, imported from the namespaces or types 'System.Web.UI.WebControls, System.Drawing'.

     

    Thanks a bunch

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 20, 2006 2:14 PM
  • User1727473813 posted

    I'm getting the error passing in the data to your ResizeSub.  I'm sorry to keep bothering, such a cool feature to have...

    'Cast from type 'InvalidCastException' to type 'String' is not valid.

     Dim c As String = System.IO.Path.GetFileName(strFileName)

    Dim strLocationOfNewFile = "C:\Inetpub\wwwroot\WebSite\Documents\" & c

    Dim NewSize = 100

    *****Cast from type 'InvalidCastException' to type 'String' is not valid. ********
    *** strLocationOfNewFile=  "C:\Inetpub\wwwroot\WebSite\Documents\file.jpg"
    *** strLocationOfNewFile=  "C:\Inetpub\wwwroot\WebSite\Documents\file.jpg"
    *** NewSize=  100
    ResizePicture(strLocationOfNewFile, strLocationOfNewFile, NewSize)

     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 20, 2006 4:17 PM
  • User1439985827 posted
    It appears that the first block of code isn't properly releasing the handle on the file, thus putting a lock on it. Try calling dispose Explicitly like this: 
    Dim FullSizePath As String = Server.MapPath("UploadedPictures/") & ImageID & ".jpg"
    Dim destinationWidth As Integer = 160
    Dim originalBitmap As Bitmap = Bitmap.FromFile(FullSizePath)
    Dim newheight As Integer = (destinationWidth / originalBitmap.Width) * originalBitmap.Height
    Dim newBitmap As Bitmap = New Bitmap(destinationWidth, newheight)
    Dim newg As Graphics = Graphics.FromImage(newBitmap)
    newg.DrawImage(originalBitmap, 0, 0, destinationWidth, newheight)
    newg.Save()
    newg.Dispose()
    newBitmap.Save(Server.MapPath("UploadedPicturesThumb/") & ImageID & sThumbExtension & ".jpg")
    newBitmap.Dispose()
    originalBitmap.Dispose()
    
    Dim destinationWidth2 As Integer = 800
    Dim originalBitmap2 As Bitmap = Bitmap.FromFile(FullSizePath)
    Dim newheight2 As Integer = (destinationWidth2 / originalBitmap2.Width) * originalBitmap2.Height
    Dim newBitmap2 As Bitmap = New Bitmap(destinationWidth2, newheight2)
    Dim newg2 As Graphics = Graphics.FromImage(newBitmap2)
    newg2.DrawImage(originalBitmap2, 0, 0, destinationWidth2, newheight2)
    newg2.Save()
    newg2.Dispose()
    newBitmap2.Save(Server.MapPath("UploadedPicturesPreview/") & ImageID & sPreviewExtension & ".jpg")
    newBitmap2.Dispose()
    originalBitmap2.Dispose()
     
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, February 14, 2007 8:24 AM

All replies

  • User1439985827 posted
    Hm, my code sample doesn't handle non-square output unfortunately. Give me a while and after work I will post something that does that later this evening.
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, September 19, 2006 1:01 PM
  • User1952191856 posted
    Awesome! thanks
    Tuesday, September 19, 2006 2:46 PM
  • User1439985827 posted
    Here is what I did. I made a function where you pass the file's path, where you want it to save the new one, then the new size you want. It will still function like the old one I wrote, but it will also do what you are looking for currently: 
    public void ResizePicture(string originalpath, string newpath, Size newsize)
    {
    	using (Bitmap newbmp = new Bitmap(newsize.Width, newsize.Height), oldbmp = Bitmap.FromFile(originalpath) as Bitmap)
    	{
    		using (Graphics newgraphics = Graphics.FromImage(newbmp))
    		{
    			newgraphics.Clear(Color.FromArgb(-1));
    			if ((float)oldbmp.Width / (float)newsize.Width == (float)oldbmp.Height / (float)newsize.Height) //Target size has a 1:1 aspect ratio
    			{
    				newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height);
    			}
    
    			else if ((float)oldbmp.Width / (float)newsize.Width > (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the top and bottom
    			{
    				newgraphics.DrawImage(oldbmp, 0f, (float)newbmp.Height / 2f - (oldbmp.Height * ((float)newbmp.Width / (float)oldbmp.Width)) / 2f, (float)newbmp.Width, oldbmp.Height * ((float)newbmp.Width / (float)oldbmp.Width));
    			}
    
    			else if ((float)oldbmp.Width / (float)newsize.Width < (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the sides
    			{
    				newgraphics.DrawImage(oldbmp, (float)newbmp.Width / 2f - (oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height)) / 2f, 0f, oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height), (float)newbmp.Height);
    			}
    
    			newgraphics.Save();
    			newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg);
    		}
    	}
    }
     a VB.NET version of it will be coming shortly for those that are interested.
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, September 19, 2006 11:33 PM
  • User1439985827 posted
    And here it is for VB.NET 2.0: 
    Sub ResizePicture(ByRef originalpath As String, ByRef newpath As String, ByVal newsize As Size)
    	Using newbmp As New Bitmap(newsize.Width, newsize.Height), oldbmp As Bitmap = CType(Bitmap.FromFile(originalpath), Image)
    		Using newgraphics As Graphics = Graphics.FromImage(newbmp)
    			newgraphics.Clear(Color.FromArgb(-1))
    			If CSng(oldbmp.Width) / CSng(newsize.Width) = CSng(oldbmp.Height) / CSng(newsize.Height) Then
    				newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height)
    			ElseIf CSng(oldbmp.Width) / CSng(newsize.Width) > CSng(oldbmp.Height) / CSng(newsize.Height) Then
    				newgraphics.DrawImage(oldbmp, 0.0F, CSng(newbmp.Height) / 2.0F - (oldbmp.Height * (CSng(newbmp.Width) / CSng(oldbmp.Width))) / 2.0F, CSng(newbmp.Width), oldbmp.Height * (CSng(newbmp.Width) / CSng(oldbmp.Width)))
    			ElseIf CSng(oldbmp.Width) / CSng(newsize.Width) < CSng(oldbmp.Height) / CSng(newsize.Height) Then
    				newgraphics.DrawImage(oldbmp, CSng(newbmp.Width) / 2.0F - (oldbmp.Width * (CSng(newbmp.Height) / CSng(oldbmp.Height))) / 2.0F, 0.0F, oldbmp.Width * (CSng(newbmp.Height) / CSng(oldbmp.Height)), CSng(newbmp.Height))
    			End If
    
    			newgraphics.Save()
    			newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg)
    		End Using
    	End Using
    End Sub
     
    Tuesday, September 19, 2006 11:56 PM
  • User1439985827 posted

    Just for fun, here it is in J#: 

    public void ResizePicture(String originalpath, String newpath, Size newsize)
    {
    	Bitmap newbmp = new Bitmap(newsize.get_Width(), newsize.get_Height()), oldbmp = (Bitmap)Bitmap.FromFile(originalpath);
    	Graphics newgraphics = Graphics.FromImage(newbmp);
    	newgraphics.Clear(Color.FromArgb(-1));
    	if ((float)oldbmp.get_Width() / (float)newsize.get_Width() == (float)oldbmp.get_Height() / (float)newsize.get_Height()) //Target size has a 1:1 aspect ratio
    	{
    		newgraphics.DrawImage(oldbmp, 0, 0, newsize.get_Width(), newsize.get_Height());
    	}
    
    	else if ((float)oldbmp.get_Width() / (float)newsize.get_Width() > (float)oldbmp.get_Height() / (float)newsize.get_Height()) //There will be white space on the top and bottom
    	{
    		newgraphics.DrawImage(oldbmp, 0f, (float)newbmp.get_Height() / 2f - (oldbmp.get_Height() * ((float)newbmp.get_Width() / (float)oldbmp.get_Width())) / 2f, (float)newbmp.get_Width(), oldbmp.get_Height() * ((float)newbmp.get_Width() / (float)oldbmp.get_Width()));
    	}
    
    	else if ((float)oldbmp.get_Width() / (float)newsize.get_Width() < (float)oldbmp.get_Height() / (float)newsize.get_Height()) //There will be white space on the sides
    	{
    		newgraphics.DrawImage(oldbmp, (float)newbmp.get_Width() / 2f - (oldbmp.get_Width() * ((float)newbmp.get_Height() / (float)oldbmp.get_Height())) / 2f, 0f, oldbmp.get_Width() * ((float)newbmp.get_Height() / (float)oldbmp.get_Height()), (float)newbmp.get_Height());
    	}
    
    	newgraphics.Save();
    	newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.get_Jpeg());
    	newgraphics.Dispose();
    	oldbmp.Dispose();
    	newbmp.Dispose();
    }
     
    Wednesday, September 20, 2006 12:11 AM
  • User1727473813 posted

    Nice, anychance you can go 1.1. vb....thanks

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 20, 2006 8:16 AM
  • User1439985827 posted
    VB.NET 1.1 Yeah no problem: here you go. I tested it and it works fine. 
    Sub ResizePicture(ByRef originalpath As String, ByRef newpath As String, ByVal newsize As Size)
    Dim newbmp As New Bitmap(newsize.Width, newsize.Height), oldbmp As Bitmap = CType(Bitmap.FromFile(originalpath), Bitmap)
    Dim newgraphics As Graphics = Graphics.FromImage(newbmp)
    newgraphics.Clear(Color.FromArgb(-1))
    If CSng(oldbmp.Width) / CSng(newsize.Width) = CSng(oldbmp.Height) / CSng(newsize.Height) Then
    newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height)
    ElseIf CSng(oldbmp.Width) / CSng(newsize.Width) > CSng(oldbmp.Height) / CSng(newsize.Height) Then
    newgraphics.DrawImage(oldbmp, 0.0F, CSng(newbmp.Height) / 2.0F - (oldbmp.Height * (CSng(newbmp.Width) / CSng(oldbmp.Width))) / 2.0F, CSng(newbmp.Width), oldbmp.Height * (CSng(newbmp.Width) / CSng(oldbmp.Width)))
    ElseIf CSng(oldbmp.Width) / CSng(newsize.Width) < CSng(oldbmp.Height) / CSng(newsize.Height) Then
    newgraphics.DrawImage(oldbmp, CSng(newbmp.Width) / 2.0F - (oldbmp.Width * (CSng(newbmp.Height) / CSng(oldbmp.Height))) / 2.0F, 0.0F, oldbmp.Width * (CSng(newbmp.Height) / CSng(oldbmp.Height)), CSng(newbmp.Height))
    End If

    newgraphics.Save()
    newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg)
    newgraphics.Dispose()
    oldbmp.Dispose()
    newbmp.Dispose()
    End Sub
     
    Wednesday, September 20, 2006 12:42 PM
  • User1952191856 posted
    Thanks!
    Wednesday, September 20, 2006 1:01 PM
  • User1439985827 posted
    Let me know how it works for the both of you.
    Wednesday, September 20, 2006 1:58 PM
  • User1727473813 posted

    Imports System.Drawing
    Imports System.Drawing.Imaging
    Imports System.Drawing.Drawing2D
    Imports System.Web
    Imports System.Web.UI
    Imports System.Web.UI.WebControls
    Imports System.Web.UI.HtmlControls

    Function UploadFile(ByVal strFile, ByVal strFileType, ByVal intRestarauntID)

     Dim strFileName As String = strFile.PostedFile.FileName
    ' Let us recover only the file name from its fully qualified path at client

    Dim c As String = System.IO.Path.GetFileName(strFileName)

    Dim strLocationOfNewFile = "C:\Inetpub\wwwroot\WebSite\Documents\" & c

    Dim NewSize = 100

    ResizePicture(strLocationOfNewFile, strLocationOfNewFile, NewSize)

    End Function

    ''Getting an issue on this line....Dim newbmp As New Bitmap

    Sub ResizePicture(ByRef originalpath As String, ByRef newpath As String, ByVal newsize As Size)

    Dim newbmp As New Bitmap(newsize.Width, newsize.Height), oldbmp As Bitmap = CType(Bitmap.FromFile(originalpath), Image)

    Dim newgraphics As Graphics = Graphics.FromImage(newbmp)

    newgraphics.Clear(Color.FromArgb(-1))

    If CSng(oldbmp.Width) / CSng(newsize.Width) = CSng(oldbmp.Height) / CSng(newsize.Height) Then

    newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height)

    ElseIf CSng(oldbmp.Width) / CSng(newsize.Width) > CSng(oldbmp.Height) / CSng(newsize.Height) Then

    newgraphics.DrawImage(oldbmp, 0.0F, CSng(newbmp.Height) / 2.0F - (oldbmp.Height * (CSng(newbmp.Width) / CSng(oldbmp.Width))) / 2.0F, CSng(newbmp.Width), oldbmp.Height * (CSng(newbmp.Width) / CSng(oldbmp.Width)))

    ElseIf CSng(oldbmp.Width) / CSng(newsize.Width) < CSng(oldbmp.Height) / CSng(newsize.Height) Then

    newgraphics.DrawImage(oldbmp, CSng(newbmp.Width) / 2.0F - (oldbmp.Width * (CSng(newbmp.Height) / CSng(oldbmp.Height))) / 2.0F, 0.0F, oldbmp.Width * (CSng(newbmp.Height) / CSng(oldbmp.Height)), CSng(newbmp.Height))

    End If

    newgraphics.Save()

    newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg)

    newgraphics.Dispose()

    oldbmp.Dispose()

    newbmp.Dispose()

    End Sub

    ERROR I GET... 

    c:\inetpub\wwwroot\\WebSite\BAL\CommonFunctions.vb(177): 'Image' is ambiguous, imported from the namespaces or types 'System.Web.UI.WebControls, System.Drawing'.

     

    Thanks a bunch

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 20, 2006 2:14 PM
  • User1439985827 posted
    That is because you are using a class that is defined in two namespaces, but you are importing both namespaces so it doesn't know which one to use. Try putting it in a seperate class that is on part of a page, or type out the full namespaces in my code.
    Wednesday, September 20, 2006 2:25 PM
  • User1727473813 posted

    Thanks..

    cast issue passing in location of file on the ResizePicture call. 

    Function UploadFile(ByVal strFile, ByVal strFileType, ByVal intRestarauntID)

     Dim c As String = System.IO.Path.GetFileName(strFileName)

    Dim strLocationOfNewFile = "C:\Inetpub\wwwroot\WebSite\Documents\" & c

    Dim NewSize = 100

    ResizePicture(strLocationOfNewFile, strLocationOfNewFile, NewSize)

    End Function

    Wednesday, September 20, 2006 3:07 PM
  • User1439985827 posted

    This line:
    Dim newbmp As New Bitmap(newsize.Width, newsize.Height), oldbmp As Bitmap = CType(Bitmap.FromFile(originalpath), Image)

    Change "Image" to "System.Drawing.Bitmap"

    I also corrected this in my original post. 

    Wednesday, September 20, 2006 4:01 PM
  • User1727473813 posted

    I'm getting the error passing in the data to your ResizeSub.  I'm sorry to keep bothering, such a cool feature to have...

    'Cast from type 'InvalidCastException' to type 'String' is not valid.

     Dim c As String = System.IO.Path.GetFileName(strFileName)

    Dim strLocationOfNewFile = "C:\Inetpub\wwwroot\WebSite\Documents\" & c

    Dim NewSize = 100

    *****Cast from type 'InvalidCastException' to type 'String' is not valid. ********
    *** strLocationOfNewFile=  "C:\Inetpub\wwwroot\WebSite\Documents\file.jpg"
    *** strLocationOfNewFile=  "C:\Inetpub\wwwroot\WebSite\Documents\file.jpg"
    *** NewSize=  100
    ResizePicture(strLocationOfNewFile, strLocationOfNewFile, NewSize)

     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, September 20, 2006 4:17 PM
  • User1439985827 posted
    NewSize is an integer, you need to be passing a Size struct. Like this: 
    Dim NewSize As System.Drawing.Size = New System.Drawing.Size(100,100)
     
    Wednesday, September 20, 2006 5:57 PM
  • User1439985827 posted

    Also, looking at the exception, for some reason this line is the one throwing the exception:

     Dim c As String = System.IO.Path.GetFileName(strFileName)

    Wednesday, September 20, 2006 5:59 PM
  • User1952191856 posted

    Just wanted to let you know its up and working beautifully.

     I did notice that sometimes it doesn't release the image as being edited, say if I go to where its saved and try to move or delete the file, so I added this to the bottom of the function and it seems to have fixed that:

    newgraphics.Dispose();

    newbmp.Dispose();

    Monday, September 25, 2006 12:36 PM
  • User1439985827 posted
    The "using" statement should take care of that once the method is over. But, whatever works for you.
    Monday, September 25, 2006 11:14 PM
  • User1952191856 posted

    Oh.. hmm I will take the disposes out then.  I wonder why it was doing that.

    I've updated it to add a watermark to the image, and each time I call it tell it where to put the watermark based on where the actual image, not the container was resized to.

     Again, thanks alot for your help.

     

    public void CreateNew(string originalpath, string newpath, Size newsize, int waterMarkFontSize, int waterMarkWidthSubtraction, int waterMarkHeightSubtraction)

    {

    using (Bitmap newbmp = new Bitmap(newsize.Width, newsize.Height), oldbmp = Bitmap.FromFile(originalpath) as Bitmap)

    {

    using (Graphics newgraphics = Graphics.FromImage(newbmp))

    {

    float intActualDrawnImageWidth = 0f;

    float intActualDrawnImageHeight = 0f;

    newgraphics.Clear(Color.FromArgb(-1));

    if ((float)oldbmp.Width / (float)newsize.Width == (float)oldbmp.Height / (float)newsize.Height) //Target size has a 1:1 aspect ratio

    {

    newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height);

    intActualDrawnImageWidth = newsize.Width;

    intActualDrawnImageHeight = newsize.Height;

    }

    else if ((float)oldbmp.Width / (float)newsize.Width > (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the top and bottom

    {

    newgraphics.DrawImage(oldbmp, 0f, (float)newbmp.Height / 2f - (oldbmp.Height * ((float)newbmp.Width / (float)oldbmp.Width)) / 2f, (float)newbmp.Width, oldbmp.Height * ((float)newbmp.Width / (float)oldbmp.Width));

    intActualDrawnImageWidth = (float)newbmp.Width;

    intActualDrawnImageHeight = oldbmp.Height * ((float)newbmp.Width / (float)oldbmp.Width);

     

    }

    else if ((float)oldbmp.Width / (float)newsize.Width < (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the sides

    {

    newgraphics.DrawImage(oldbmp, (float)newbmp.Width / 2f - (oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height)) / 2f, 0f, oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height), (float)newbmp.Height);

    intActualDrawnImageWidth = oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height);

    intActualDrawnImageHeight = (float)newbmp.Height;

    }

    SolidBrush semiTransparentBrush = new SolidBrush(Color.FromArgb(130, 247, 255, 121));

    newgraphics.DrawString("Website.com",

    new Font("Arial", waterMarkFontSize, FontStyle.Regular), semiTransparentBrush,

    new RectangleF(intActualDrawnImageWidth - waterMarkWidthSubtraction, intActualDrawnImageHeight - waterMarkHeightSubtraction, 500, 100));

    newgraphics.Save();

    newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg);

    newgraphics.Dispose();

    newbmp.Dispose();

    }

    }

    }

    Wednesday, September 27, 2006 6:09 PM
  • User1439985827 posted
    This code sample is available for download in my Helpers Library, which can be downloaded here: http://blogs.strongcoders.com/files/folders/kevins_code_samples/default.aspx
    Saturday, September 30, 2006 4:06 PM
  • User-1620578816 posted

    I've been trying the 'vb' version (ap.net 2.0) but keep getting the following error...

    'Type bitmap Not Defined'

     The following line is highlighted...

    Dim originalBitmap As Bitmap = Bitmap.FromFile(FileToResize, True)

    I have declared the follwoing at the top of the web page

    <%@ Import Namespace="System.Drawing.Drawing2D" %>
    <%@ Import Namespace="System.Drawing.Imaging" %>
    <%@ Import Namespace="System.Web" %>
    <%@ Import Namespace="System.Web.UI" %>
    <%@ Import Namespace="Web.UI.WebControls" %>
    <%@ Import Namespace="Web.UI.HtmlControls" %> 

    Any ideas to where i'm going wrong?

     Thanks


     

    Wednesday, October 4, 2006 10:42 AM
  • User1439985827 posted

    You got every namespace except the right one [:)]. 

    <%@ Import Namespace="System.Drawing" %>
     
    Wednesday, October 4, 2006 1:16 PM
  • User-1620578816 posted

    You got every namespace except the right one [:)]. 

    <%@ Import Namespace="System.Drawing" %>

     

    [:$] 

    Many thanks that's fixed it, dunno how I missed that !

    Also, in the vb version how do I adapt it so....

    Sub 1. 

    The uploaded image is resized to a height of 210 and the width auto adjusted (so at to maintain aspect ratio).

    The original file is then deleted unless it's height <= 210, in which case it i skept and no resize occurs.

    And in a seperate, different sub,,,,

    (Doesn't matter if orig pic is in potrtait or landscape mode)

    Sub 2

    The uploaded image is resized to a width of 800 and the height is auto adjusted (so as to maintain aspect ratio).

    A second image is resized from the original file to a thumbnail width of 200 and height adjusted as above.

    The original file is then deleted unless it's width <= 800, in which case it is kept and no resize occurs. (still resizes thumb)

    (Doesn't matter if orig pic is in potrtait or landscape mode)

     Many thanks

     

    Thursday, October 5, 2006 3:47 PM
  • User-1290360778 posted

    Hi,  I am new to C# and am trying to get my head around it.  I found a source demo for uploading images and resizing them but it used the getThumbNail ...  which made the resized jpg dithered/grainy.

     I have since tried your function but get:


    Compiler Error Message: CS1502: The best overloaded method match for 'ImageUpload.ResizePicture(string, string, System.Drawing.Size)' has some invalid arguments

    Source Error:

     
    Line 39: 		int iheight = 480;
    Line 40:             //run vcsjones resize function
    Line 41:             ResizePicture(imageUrl,imageUrl,640);
    Line 42: 
    Line 43: 	   }


    Source File: e:\websites\test\BuoyRacer\ImageUpload.aspx.cs Line: 41

    Show Detailed Compiler Output:

    E:\Microsoft Visual Studio 8\Common7\IDE> "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe" /t:library /utf8output /R:"C:\WINDOWS\assembly\GAC_MSIL\System.Configuration\2.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll" /R:"C:\WINDOWS\assembly\GAC_32\System.Web\2.0.0.0__b03f5f7f11d50a3a\System.Web.dll" /R:"C:\WINDOWS\assembly\GAC_MSIL\System\2.0.0.0__b77a5c561934e089\System.dll" /R:"C:\WINDOWS\assembly\GAC_MSIL\System.Drawing\2.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll" /R:"C:\WINDOWS\assembly\GAC_MSIL\System.Web.Services\2.0.0.0__b03f5f7f11d50a3a\System.Web.Services.dll" /R:"C:\WINDOWS\assembly\GAC_32\System.EnterpriseServices\2.0.0.0__b03f5f7f11d50a3a\System.EnterpriseServices.dll" /R:"C:\WINDOWS\assembly\GAC_MSIL\System.Xml\2.0.0.0__b77a5c561934e089\System.Xml.dll" /R:"C:\WINDOWS\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll" /R:"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll" /R:"C:\WINDOWS\assembly\GAC_MSIL\System.Web.Mobile\2.0.0.0__b03f5f7f11d50a3a\System.Web.Mobile.dll" /out:"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\buoyracer\7a2e8cbc\9c8582e9\App_Web_imageupload.aspx.cdcab7d2.eikbwwtw.dll" /debug- /optimize+ /w:4 /nowarn:1659;1699  "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\buoyracer\7a2e8cbc\9c8582e9\App_Web_imageupload.aspx.cdcab7d2.eikbwwtw.0.cs" "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\buoyracer\7a2e8cbc\9c8582e9\App_Web_imageupload.aspx.cdcab7d2.eikbwwtw.1.cs" "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\buoyracer\7a2e8cbc\9c8582e9\App_Web_imageupload.aspx.cdcab7d2.eikbwwtw.2.cs"
    
    
    Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.42
    for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727
    Copyright (C) Microsoft Corporation 2001-2005. All rights reserved.
    
    e:\websites\test\BuoyRacer\ImageUpload.aspx.cs(41,13): error CS1502: The best overloaded method match for 'ImageUpload.ResizePicture(string, string, System.Drawing.Size)' has some invalid arguments
    e:\websites\test\BuoyRacer\ImageUpload.aspx.cs(41,45): error CS1503: Argument '3': cannot convert from 'int' to 'System.Drawing.Size'

    Here is my entire cs file in vs2005  Can anyone tell me where I am going wrong:

    using System;

    using System.Data;

    using System.Drawing.Imaging;

    using System.Drawing;

    using System.Configuration;

    using System.Collections;

    using System.Web;

    using System.Web.Security;

    using System.Web.UI;

    using System.Web.UI.WebControls;

    using System.Web.UI.WebControls.WebParts;

    using System.Web.UI.HtmlControls;

     

    public partial class ImageUpload : System.Web.UI.Page

    {

    public void UploadBtn_Click(Object sender, EventArgs e)

    {

    String UploadedFile = MyFile.PostedFile.FileName;

    int ExtractPos = UploadedFile.LastIndexOf("\\") + 1;

    //to retrieve only Filename from the complete path

    String UploadedFileName = UploadedFile.Substring(ExtractPos,UploadedFile.Length - ExtractPos);

    // Display information about posted file. Div is invisible by default

    FileName.InnerHtml = UploadedFileName;

    MyContentType.InnerHtml = MyFile.PostedFile.ContentType;

    ContentLength.InnerHtml = MyFile.PostedFile.ContentLength.ToString();

    FileDetails.Visible = true; //div is made visible

    // Save uploaded file to server at the in the Pics folder

    MyFile.PostedFile.SaveAs(Request.PhysicalApplicationPath + "pics\\" + UploadedFileName );

    System.Drawing.Image oImg = System.Drawing.Image.FromFile(Request.PhysicalApplicationPath + "pics\\" + UploadedFileName );

    //resize creation starts

    try

    {

    String imageUrl= UploadedFileName;

    imageUrl = "pics/" + imageUrl;

    System.Drawing.Image fullSizeImg = System.Drawing.Image.FromFile(Server.MapPath(imageUrl));

     

    int iwidth = 640;

    int iheight = 480;

    //run vcsjones resize function

    ResizePicture(imageUrl,imageUrl,640);

    }

    catch(Exception ex){

    Response.Write("An error occurred - " + ex.ToString());}

    }

     

    //vcsjones resize function

    public void ResizePicture(string originalpath, string newpath, Size newsize)

    {

    using (Bitmap newbmp = new Bitmap(newsize.Width, newsize.Height), oldbmp = Bitmap.FromFile(originalpath) as Bitmap)

    {

    using (Graphics newgraphics = Graphics.FromImage(newbmp))

    {

    newgraphics.Clear(Color.FromArgb(-1));

    if ((float)oldbmp.Width / (float)newsize.Width == (float)oldbmp.Height / (float)newsize.Height) //Target size has a 1:1 aspect ratio

    {

    newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height);

    }

    else if ((float)oldbmp.Width / (float)newsize.Width > (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the top and bottom

    {

    newgraphics.DrawImage(oldbmp, 0f, (float)newbmp.Height / 2f - (oldbmp.Height * ((float)newbmp.Width / (float)oldbmp.Width)) / 2f, (float)newbmp.Width, oldbmp.Height * ((float)newbmp.Width / (float)oldbmp.Width));

    }

    else if ((float)oldbmp.Width / (float)newsize.Width < (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the sides

    {

    newgraphics.DrawImage(oldbmp, (float)newbmp.Width / 2f - (oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height)) / 2f, 0f, oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height), (float)newbmp.Height);

    }

    newgraphics.Save();

    newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg);

    }

    }

    }

    }

     

    Wednesday, October 11, 2006 6:01 PM
  • User1439985827 posted

    That is because Size is not a number, it is the structure Size. Here is an example:

    ResizePicture(imageUrl,imageUrl,new Size(480, 640));

    Wednesday, October 11, 2006 6:05 PM
  • User-1290360778 posted

    Thanks heaps for that.

     

    Now I get:

    An error occurred - System.IO.FileNotFoundException: pics/DSC02714.JPG at System.Drawing.Image.FromFile(String filename, Boolean useEmbeddedColorManagement) at System.Drawing.Image.FromFile(String filename) at ImageUpload.ResizePicture(String originalpath, String newpath, Size newsize) at ImageUpload.UploadBtn_Click(Object sender, EventArgs e)

    Is it because it is not doing a mapPath to my folders?  I have modified my page so I now have two folders one for the originals and one for the resized so I can setup an auto slideshow over the resized folder.

     

    String imageUrl = UploadedFileName;

    String imageUrlRS = UploadedFileName;

    imageUrl = "pics/" + imageUrl;

    imageUrlRS = "picsR/" + imageUrlRS;

    System.Drawing.Image fullSizeImg = System.Drawing.Image.FromFile(Server.MapPath(imageUrl));

     

    int iwidth = 640;

    int iheight = 480;

    //run vcsjones resize function

    ResizePicture(imageUrl, imageUrl, new Size(480, 640));

    Wednesday, October 11, 2006 6:24 PM
  • User-1290360778 posted

    Many thanks for the help.  I added the Mappath in and all is behaving very nicely............Now I just need to keep going and migrate my head from classic asp to c#[:)] 

    Cheers

    Mike

     

     

    imageUrl = Server.MapPath(imageUrl);

    imageUrlRS = Server.MapPath(imageUrlRS);

    int iwidth = 640;

    int iheight = 480;

    //run vcsjones resize function

    ResizePicture(imageUrl, imageUrlRS, new Size(640, 480));

    Wednesday, October 11, 2006 7:33 PM
  • User1735239612 posted

    anyone know how to remove the whitespace created from the resize?

     thx!

    Monday, January 29, 2007 1:05 PM
  • User1548968958 posted

    i'd also be very interested....

    thanks 

    Tuesday, January 30, 2007 9:36 AM
  • User1548968958 posted

    anyone know how to remove the whitespace created from the resize?

     thx!

     

    Right, have had a little play and think i've cracked it.  I'm still a bit new to asp .net so bare with me if it seems like a hack.  The basics of it is that it first works out what shape it is - portrait, landscape or a square.  It then keeps the longest side and calculates a ratio and then applies it to the shorter side so the aspect is kept.  Only after it has worked out the new dimensions then it will create a new Bitmap.

     

        Sub ResizePicture(ByRef originalpath As String, ByRef newpath As String, ByVal newsize As Size)
    
            Using oldbmp As Bitmap = CType(Bitmap.FromFile(originalpath), Image)
                If CSng(oldbmp.Width) > CSng(oldbmp.Height) Then        'landscape
                    newsize.Height = oldbmp.Height / (oldbmp.Width / newsize.Width)
                    Response.Write("Landscape: W=" & newsize.Width & " H=" & newsize.Height)
                ElseIf CSng(oldbmp.Height) > CSng(oldbmp.Width) Then    'portrait
                    newsize.Width = oldbmp.Width / (oldbmp.Height / newsize.Height)
                    Response.Write("Portrait: W=" & newsize.Width & " H=" & newsize.Height)
                ElseIf CSng(oldbmp.Width) = CSng(oldbmp.Height) Then    'square
                    If newsize.Width > newsize.Height Then              'get the shortest side
                        newsize.Width = newsize.Height
                    Else
                        newsize.Height = newsize.Width
                    End If
                    Response.Write("Square: W=" & newsize.Width & " H=" & newsize.Height)
                End If
    
    
                Using newbmp As New Bitmap(newsize.Width, newsize.Height)
                    Using newgraphics As Graphics = Graphics.FromImage(newbmp)
                        newgraphics.Clear(Color.FromArgb(-1))
                        newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height)
                        newgraphics.Save()
                        newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg)
                    End Using
                End Using
            End Using
        End Sub
      

     

    Tuesday, January 30, 2007 11:08 AM
  • User1735239612 posted

    u da man! - it works great - thank you!

    here it is converted to c#

    public static void ResizePicture(string originalpath, string newpath, Size newsize)

    {

       using (Bitmap oldbmp = Bitmap.FromFile(originalpath) as Bitmap)

       {

          if (oldbmp.Width > oldbmp.Height)

          {

             //landscape

             newsize.Height = oldbmp.Height / (oldbmp.Width / newsize.Width);

          }

          else if (oldbmp.Height > oldbmp.Width)

          {

             //portrait

             newsize.Width = oldbmp.Width / (oldbmp.Height / newsize.Height);

          }

          else if (oldbmp.Width == oldbmp.Height)

          {

              //square

              if (newsize.Width > newsize.Height)//get the shortest side

                  newsize.Width = newsize.Height;

              else

                  newsize.Height = newsize.Width;

          }

     

          using (Bitmap newbmp = new Bitmap(newsize.Width, newsize.Height))

          {

              using (Graphics newgraphics = Graphics.FromImage(newbmp))

              {

                  newgraphics.Clear(Color.FromArgb(-1));

                  newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height);

                 newgraphics.Save();

                 newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg);

              }

        }

    }//end using oldbmp

    }//end method

    Tuesday, January 30, 2007 12:47 PM
  • User2051245708 posted

    I've been successfully using this script to create thumbnails images (thanks Kevin!) but I want to run the script a second time to create an image of a different size.

    The script needs to run after the create thumbnail script (i.e. on the same page). But when it does it creates a GDI+ error.

    This is the script:

     

    1    Dim FullSizePath As String = Server.MapPath("UploadedPictures/") & ImageID & ".jpg"
    2    Dim destinationWidth As Integer = 160
    3    Using originalBitmap As Bitmap = Bitmap.FromFile(FullSizePath)
    4      Dim newheight As Integer = (destinationWidth / originalBitmap.Width) * originalBitmap.Height
    5      Using newBitmap As Bitmap = New Bitmap(destinationWidth, newheight)
    6       Using newg As Graphics = Graphics.FromImage(newBitmap)
    7        newg.DrawImage(originalBitmap, 0, 0, destinationWidth, newheight)
    8        newg.Save()
    9       End Using
    10     newBitmap.Save(Server.MapPath("UploadedPicturesThumb/") & ImageID & sThumbExtension & ".jpg")
    11     End Using
    12   End Using
    13   
    14   Dim destinationWidth2 As Integer = 800
    15   Using originalBitmap2 As Bitmap = Bitmap.FromFile(FullSizePath)
    16     Dim newheight2 As Integer = (destinationWidth2 / originalBitmap2.Width) * originalBitmap2.Height
    17     Using newBitmap2 As Bitmap = New Bitmap(destinationWidth2, newheight2)
    18      Using newg2 As Graphics = Graphics.FromImage(newBitmap2)
    19       newg2.DrawImage(originalBitmap2, 0, 0, destinationWidth2, newheight2)
    20       newg2.Save()
    21      End Using
    22     newBitmap2.Save(Server.MapPath("UploadedPicturesPreview/") & ImageID & sPreviewExtension & ".jpg")
    23     End Using
    24   End Using
    
      
    Wednesday, February 14, 2007 5:56 AM
  • User1439985827 posted
    What is the full exception? What line does it throw this error at?
    Wednesday, February 14, 2007 7:44 AM
  • User2051245708 posted

    Hi Kevin

    Exception Details: System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI+.

    Line:  newBitmap2.Save(Server.MapPath("UploadedPicturesPreview/") & ImageID & sPreviewExtension & ".jpg")

     
    I have checked that I have full rights to that folder as I am able to write to 2 other folders (one for the fullsize image & one for the thumbnails). So I don't thing write/access permissions is the problem.
    no hang on...if I change UploadedPicturesPreview to one of the other folder names it works! That's got me stumped! There was no difference between the folders permissions.
    Sorry for my previous post.

     

     

    Wednesday, February 14, 2007 8:09 AM
  • User1439985827 posted
    It appears that the first block of code isn't properly releasing the handle on the file, thus putting a lock on it. Try calling dispose Explicitly like this: 
    Dim FullSizePath As String = Server.MapPath("UploadedPictures/") & ImageID & ".jpg"
    Dim destinationWidth As Integer = 160
    Dim originalBitmap As Bitmap = Bitmap.FromFile(FullSizePath)
    Dim newheight As Integer = (destinationWidth / originalBitmap.Width) * originalBitmap.Height
    Dim newBitmap As Bitmap = New Bitmap(destinationWidth, newheight)
    Dim newg As Graphics = Graphics.FromImage(newBitmap)
    newg.DrawImage(originalBitmap, 0, 0, destinationWidth, newheight)
    newg.Save()
    newg.Dispose()
    newBitmap.Save(Server.MapPath("UploadedPicturesThumb/") & ImageID & sThumbExtension & ".jpg")
    newBitmap.Dispose()
    originalBitmap.Dispose()
    
    Dim destinationWidth2 As Integer = 800
    Dim originalBitmap2 As Bitmap = Bitmap.FromFile(FullSizePath)
    Dim newheight2 As Integer = (destinationWidth2 / originalBitmap2.Width) * originalBitmap2.Height
    Dim newBitmap2 As Bitmap = New Bitmap(destinationWidth2, newheight2)
    Dim newg2 As Graphics = Graphics.FromImage(newBitmap2)
    newg2.DrawImage(originalBitmap2, 0, 0, destinationWidth2, newheight2)
    newg2.Save()
    newg2.Dispose()
    newBitmap2.Save(Server.MapPath("UploadedPicturesPreview/") & ImageID & sPreviewExtension & ".jpg")
    newBitmap2.Dispose()
    originalBitmap2.Dispose()
     
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, February 14, 2007 8:24 AM
  • User-2005984166 posted

    Hi vcsjones,

    thanks for this it's been invaluble in a blog project i'm working on!

    the only issue i have is the image seems to get 'crunched' when it's resized, especially when resizing from a large size image 1000+px to say 100px, is there any way of smoothing the image while resizing?

    I'm using c# by the way.

    Cheers

    Monday, June 25, 2007 7:05 AM
  • User1735239612 posted

     

    1            /// <summary>
    2            /// Resizes the picture.
    3            /// </summary>
    4            /// <param name="originalpath">The originalpath.</param>
    5            /// <param name="newpath">The newpath.</param>
    6            /// <param name="newsize">The newsize.</param>
    7            /// <param name="addDate">if set to <c>true</c> [add date].</param>
    8            public static void ResizePicture(string originalpath, string newpath, Size newsize, bool addDate)
    9            {
    10               using (Bitmap newbmp = new Bitmap(newsize.Width, newsize.Height), oldbmp = Bitmap.FromFile(originalpath) as Bitmap)
    11               {
    12                   using (Graphics newgraphics = Graphics.FromImage(newbmp))
    13                   {
    14                       newgraphics.Clear(Color.FromArgb(-1));
    15   
    16                       if ((float)oldbmp.Width / (float)newsize.Width == (float)oldbmp.Height / (float)newsize.Height) //Target size has a 1:1 aspect ratio 
    17                       {
    18                           newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height);
    19                       }
    20                       else if ((float)oldbmp.Width / (float)newsize.Width > (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the top and bottom. 
    21                       {
    22                           newgraphics.DrawImage(oldbmp, 0f, (float)newsize.Height / 2f - (oldbmp.Height * ((float)newsize.Width / (float)oldbmp.Width)) / 2f, (float)newsize.Width, oldbmp.Height * ((float)newsize.Width / (float)oldbmp.Width));
    23                       }
    24                       else if ((float)oldbmp.Width / (float)newsize.Width < (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the sides. 
    25                       {
    26                           newgraphics.DrawImage(oldbmp, (float)newbmp.Width / 2f - (oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height)) / 2f, 0f, oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height), (float)newbmp.Height);
    27                       }
    28                       if (addDate)
    29                       {
    30                           using (SolidBrush newBrush = new SolidBrush(Color.Black))
    31                           {
    32                               using (Brush fillBrush = new SolidBrush(Color.White))
    33                               {
    34                                   RectangleF rect = new RectangleF(0, newsize.Height - 20, newsize.Width, 20);
    35                                   newgraphics.FillRectangle(fillBrush, rect);
    36                                   // Create the date, centered. 
    37                                   using (StringFormat stringFormat = new StringFormat())
    38                                   {
    39                                       stringFormat.Alignment = StringAlignment.Center;
    40                                       stringFormat.LineAlignment = StringAlignment.Center;
    41                                       newgraphics.DrawString(DateTime.Now.ToShortDateString(),new Font("Arial", 8, FontStyle.Regular), newBrush, rect, stringFormat);
    42                                   }
    43                                   newgraphics.Save();
    44                               }
    45                               //End using fillBrush. 
    46                           }
    47                           //End using newBrush. 
    48                       }
    49                       newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg);
    50                   }
    51                   //End using newgraphics. 
    52               }
    53               //End using newbmp. 
    54           }
    55      
    
     
    Monday, June 25, 2007 9:30 AM
  • User-2005984166 posted

    Nice Joe!

    solved my crunchy image problem thought i'd post the solution in case anyone else wanted to use it:

     

    public void ResizePicture(string originalpath, string newpath, Size newsize)
    	{
    		using (Bitmap newbmp = new Bitmap(newsize.Width, newsize.Height), oldbmp = Bitmap.FromFile(originalpath) as Bitmap)
    		{
    			using (Graphics newgraphics = Graphics.FromImage(newbmp))
    			{
    				newgraphics.Clear(Color.FromArgb(-1));
    			//this line added to set interpolationMode to high quality
                                                                    newgraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
    				if ((float)oldbmp.Width / (float)newsize.Width == (float)oldbmp.Height / (float)newsize.Height) //Target size has a 1:1 aspect ratio
    				{
    					newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height);
    				}
    				else if ((float)oldbmp.Width / (float)newsize.Width > (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the top and bottom
    				{
    					newgraphics.DrawImage(oldbmp, 0f, (float)newbmp.Height / 2f - (oldbmp.Height * ((float)newbmp.Width / (float)oldbmp.Width)) / 2f, (float)newbmp.Width, oldbmp.Height * ((float)newbmp.Width / (float)oldbmp.Width));
    				}
    				else if ((float)oldbmp.Width / (float)newsize.Width < (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the sides
    				{
    					newgraphics.DrawImage(oldbmp, (float)newbmp.Width / 2f - (oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height)) / 2f, 0f, oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height), (float)newbmp.Height);
    				}
    				newgraphics.Save();
    				newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg);
    			}
    		}
    	}
     

     

    Monday, June 25, 2007 11:00 AM
  • User-727849386 posted

    Hi Kevin, Thanks for this. It's great!! Can you give me any idea as to how I would crop the image to a specified size, instead of resizing it? k.

    Thursday, July 26, 2007 7:32 PM
  • User1439985827 posted

    Here is a method for cropping an image: 

            /// <summary>
            /// Crop a Bitmap object and save it to another file.
            /// </summary>
            /// <param name="pathOfImageToCrop">The full File Path of the image to crop.</param>
            /// <param name="saveAs">The path including the filename to save the cropped image.</param>
            /// <param name="topLeftCorner">The Point which the cropping will start from.</param>
            /// <param name="cropSize">The size of the cropped region.</param>
            public static void CropPicture(string pathOfImageToCrop, string saveAs, Point topLeftCorner, Size cropSize)
            {
                using (Bitmap originalBmp = new Bitmap(pathOfImageToCrop), newBitmap = new Bitmap(cropSize.Width, cropSize.Height))
                {
                    using (Graphics newGraphics = Graphics.FromImage(newBitmap))
                    {
                        newGraphics.DrawImageUnscaledAndClipped(originalBmp, new Rectangle(topLeftCorner, cropSize));
                        newGraphics.Save();
                    }
                    newBitmap.Save(saveAs);
                }
            }
     
    Thursday, July 26, 2007 10:08 PM
  • User139771134 posted

    Kevin,

    You seem to be the go-to guy for GDI and images.

    I have a method that resizes the image that the user uploads and saves the smaller version (both a thumbnail and a 300x300) of that image on the server. However, if the file that's being uploaded is large (2-3mbs) it takes a REALLY long time (obviously due to bandwith).  I have seen other sites handle/resize the same exact image much faster.  It's as if the image is resized before it is ever uploaded - thus making the upload faster.  Any idea how this is being done? 

    Thanks in advance.

    Monday, July 30, 2007 2:51 PM
  • User1439985827 posted

    Sorry for the late reply,

    Can you give an example of a site that has this behavior?

    Sunday, August 5, 2007 7:50 PM
  • User139771134 posted

    Facebook.com,

    When you create picture albums,

    1st) they generate previews of all the images in your local directory (very quickly despite the image size)

    2nd) when you upload those images it's very quick also.  i've tried uploading the same image, via the same connection in my code and it's about 8-10 times longer.

     i've talked to some people and heard it might be through javascript libraries...

    Monday, August 6, 2007 9:26 AM
  • User1439985827 posted

    Facebook uses an Active X Control, meaning that all of their image resizing is being handled by the ActiveX Control, same with the previews. Using Facebook, the Resize is done before it is sent to the server, thus speeding up the upload and resize. If you upload images to Face Book using the "Simple upload thinger" (Honestly, that is what it is called on the site) that does not use ActiveX Objects, you will see that it takes just as long.

    I hope that answers your question.

    i've talked to some people and heard it might be through javascript libraries...

    To my personal knowledge, I do not think it is possible to truely resize an image using just JavaScript.

    Monday, August 6, 2007 4:11 PM
  • User139771134 posted

    Thanks for checking into it.

     Any idea where I can get more information on writing/finding an Active X control that would let me perform that functionality?

    Wednesday, August 8, 2007 9:35 AM
  • User1439985827 posted

    it wouldn't be that difficult to write one using VB6 or ATL in C++, but you'll need a lot of familiarity with ActiveX and COM. If you are looking to purchase one, Googling one isn't difficult to come up with a few promising results. I can't say I have any background writing an ActiveX control for image resizing and file uploads.

    Wednesday, August 8, 2007 9:59 AM
  • User-1921773091 posted

     Hi there,

     I am successfully uploading and resizing my images (all JPGs) while maintaining good quality, save for one issue. My resized image has an imperfection along the edges. Specifically, there is an inner square, one pixel in thickness, that is located one pixel inside the outer border, all the way around. This inner square is not a constant color, but more like several shades lighter than what each pixel should be at that position. I am not creating any watermarks, so this issue seems quite odd. I am running .NET 1.1. My code is below:

             

    	Dim myNewbitmap As New Bitmap(bmp, 300, 300)
    Dim myresizer As Graphics

    myresizer = Graphics.FromImage(myNewbitmap)
    myresizer.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
    myresizer.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
    myresizer.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
    myresizer.CompositingQuality = Drawing2D.CompositingQuality.HighQuality

    myresizer.DrawImage(bmp, 0, 0, 300, 300)

    Dim objImageCodecInfo1 As ImageCodecInfo
    Dim objEncoder0 As Encoder
    Dim objEncoderParameter0 As EncoderParameter
    Dim objEncoderParameters1 As EncoderParameters

    ' Get an ImageCodecInfo object that represents the JPEG codec. objImageCodecInfo1 = GetEncoderInfo("image/jpeg")
    objEncoder0 = Encoder.Quality

    objEncoderParameters1 = New EncoderParameters(1)

    objEncoderParameter0 = New EncoderParameter(objEncoder0, CType(100L, Int32))
    objEncoderParameters1.Param(0) = objEncoderParameter0

    myNewbitmap.Save(strPath, objImageCodecInfo1, objEncoderParameters1)

    'using the Save method below fixes the problem, but the overall quality of the image is much worse
    'myNewbitmap.Save(strPath, System.Drawing.Imaging.ImageFormat.Jpeg)
    myNewbitmap.Dispose() myresizer.Dispose()

     

    Any ideas?

    Thanks,

    Alex 

    Sunday, August 12, 2007 3:09 AM
  • User1439985827 posted

    If you are using the Windows Picture and Fax Viewer (the thing built into Windows) to look at your JPGs, it does this when you zoom in. I tested you code, and it works fine. The easy way to test this is to zoom in using the Windows Viewer on the original picture, and it will do it anyways. Another good way to test this behavior is to open your JPG into MS Paint, and zoom in using it.

    Sunday, August 12, 2007 3:58 AM
  • User-1921773091 posted

     I've zoomed in on the images using Photoshop and still see it, so I think it is more than a problem with the image viewing application. Here is an example:

    Inner border issue

    As another test, I uploaded a completely black JPG and didn't get the border. Could this be a .NET 1.1 issue?

    Thanks!

    Alex 

    Sunday, August 12, 2007 11:58 AM
  • User1439985827 posted

    Ah, Hmm... I didn't get those results. I'll play around with it a little more. I tested your code in VS 2003, I'll try it with a few different images.

    Sunday, August 12, 2007 2:03 PM
  • User1439985827 posted

    Alex,

    I was able to reproduce the issue. It was doing it the whole time for me, however it was much less visible that the image you posted above. I changed your code and it seems to work OK for me now. However, there appears to be some differences with our environments. Here is my complete code:  

    Imports System.Drawing
    Imports System.IO
    Imports System.Drawing.Imaging
    
    Module Module1
    
        Sub Main()
            Dim bmp As Bitmap
            bmp = Bitmap.FromFile("C:\user_new.jpg")
            Dim myNewbitmap As New Bitmap(bmp, 300, 300)
    
            Dim objImageCodecInfo1 As ImageCodecInfo
            Dim objEncoder0 As Encoder
            Dim objEncoderParameter0 As EncoderParameter
            Dim objEncoderParameters1 As EncoderParameters
            objImageCodecInfo1 = GetEncoderInfo("image/jpeg")
            objEncoder0 = Encoder.Quality
            objEncoderParameters1 = New EncoderParameters(1)
            objEncoderParameter0 = New EncoderParameter(objEncoder0, 100L)
            objEncoderParameters1.Param(0) = objEncoderParameter0
            Dim fs As FileStream = New FileStream("C:\myjpg.jpg", FileMode.OpenOrCreate, FileAccess.Write)
            myNewbitmap.Save(fs, objImageCodecInfo1, objEncoderParameters1)
            myNewbitmap.Dispose()
            fs.Close()
        End Sub
    
        Public Function GetEncoderInfo(ByRef mimeType As String)
            For Each ici As ImageCodecInfo In System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()
                If ici.MimeType.Equals(mimeType) Then
                    Return ici
                End If
            Next
            Return Nothing
        End Function
    
    End Module
    

     What I did was remove the use of the Graphics object. Since the Bitmap class can use another Bitmap class in its constructor along with the new size. This seemed to correct the issue, and make the code a little simpler.

    Sunday, August 12, 2007 9:50 PM
  • User2110019919 posted

    Hello all!

    Would I be able to resize the image straight from the posted file from the asp file upload control? CType(System.Drawing.Image.FromStream(image_upload.PostedFile.InputStream), Bitmap)

    I am having some difficulties trying to fit that in to the sub. I want to avoid saving the file then resizing it, I want to do the resizing on the fly if possible.

      

    Sub image_upload_btn_Click(ByVal sender As Object, ByVal e As EventArgs) Handles image_upload_btn.Click
    
            If (CheckFileType(image_upload.PostedFile.FileName)) Then
                Dim FilePath As String = "~/_Image/images/ApplicantPhotos/" & "applicant_" & image_name_hdn.Value & ".jpg"
                image_upload.SaveAs(MapPath(FilePath))
                image_upload.Dispose()
                Dim NewSize As System.Drawing.Size = New System.Drawing.Size(100, 133)
                Dim originalBitmap As Bitmap = CType(System.Drawing.Image.FromStream(image_upload.PostedFile.InputStream), Bitmap)
                ResizePicture(originalBitmap, FilePath, NewSize)
    
                Dim upFolder As String = "/_Image/images/ApplicantPhotos/" & "applicant_" & image_name_hdn.Value & ".jpg"
                Image1.ImageUrl = upFolder
            Else
                errormessage2_lbl.Text = "Only .jpg files are allowed!"
            End If
        End Sub
    
        Sub ResizePicture(ByRef ImgToResize As Bitmap, ByRef newpath As String, ByVal newsize As Size)
            Using newbmp As New Bitmap(newsize.Width, newsize.Height), oldbmp As Bitmap = ImgToResize
    
                Using newgraphics As Graphics = Graphics.FromImage(newbmp)
                    newgraphics.Clear(Color.FromArgb(-1))
                    If CSng(oldbmp.Width) / CSng(newsize.Width) = CSng(oldbmp.Height) / CSng(newsize.Height) Then
                        newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height)
                    ElseIf CSng(oldbmp.Width) / CSng(newsize.Width) > CSng(oldbmp.Height) / CSng(newsize.Height) Then
                        newgraphics.DrawImage(oldbmp, 0.0F, CSng(newbmp.Height) / 2.0F - (oldbmp.Height * (CSng(newbmp.Width) / CSng(oldbmp.Width))) / 2.0F, CSng(newbmp.Width), oldbmp.Height * (CSng(newbmp.Width) / CSng(oldbmp.Width)))
                    ElseIf CSng(oldbmp.Width) / CSng(newsize.Width) < CSng(oldbmp.Height) / CSng(newsize.Height) Then
                        newgraphics.DrawImage(oldbmp, CSng(newbmp.Width) / 2.0F - (oldbmp.Width * (CSng(newbmp.Height) / CSng(oldbmp.Height))) / 2.0F, 0.0F, oldbmp.Width * (CSng(newbmp.Height) / CSng(oldbmp.Height)), CSng(newbmp.Height))
                    End If
    
                    newgraphics.Save()
                    newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg)
                    newbmp.Dispose()
                End Using
            End Using
        End Sub
     

     

    Thanks,

     

    Robert

    Monday, August 13, 2007 11:30 AM
  • User2110019919 posted

    I figured it out, sloppy coding on my end. I will play around with this code and the other code to make the image more pretty!

     

     

    Sub image_upload_btn_Click(ByVal sender As Object, ByVal e As EventArgs) Handles image_upload_btn.Click
    
            If (CheckFileType(image_upload.PostedFile.FileName)) Then
                Dim FilePath As String = "~/_Image/images/ApplicantPhotos/" & "applicant_" & image_name_hdn.Value & ".jpg"
                image_upload.SaveAs(MapPath(FilePath))
                Dim NewSize As System.Drawing.Size = New System.Drawing.Size(100, 133)
                Dim originalBitmap As Bitmap = CType(System.Drawing.Image.FromStream(image_upload.PostedFile.InputStream), Bitmap)
                ResizePicture(originalBitmap, FilePath, NewSize)
    
                'Dim upFolder As String = "/_Image/images/ApplicantPhotos/" & "applicant_" & image_name_hdn.Value & ".jpg"
                'Image1.ImageUrl = upFolder
            Else
                errormessage2_lbl.Text = "Only .jpg files are allowed!"
            End If
        End Sub
    
        Sub ResizePicture(ByRef ImgToResize As Bitmap, ByRef newpath As String, ByVal newsize As Size)
            Using newbmp As New Bitmap(newsize.Width, newsize.Height), oldbmp As Bitmap = ImgToResize
    
                Using newgraphics As Graphics = Graphics.FromImage(newbmp)
                    newgraphics.Clear(Color.FromArgb(-1))
                    If CSng(oldbmp.Width) / CSng(newsize.Width) = CSng(oldbmp.Height) / CSng(newsize.Height) Then
                        newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height)
                    ElseIf CSng(oldbmp.Width) / CSng(newsize.Width) > CSng(oldbmp.Height) / CSng(newsize.Height) Then
                        newgraphics.DrawImage(oldbmp, 0.0F, CSng(newbmp.Height) / 2.0F - (oldbmp.Height * (CSng(newbmp.Width) / CSng(oldbmp.Width))) / 2.0F, CSng(newbmp.Width), oldbmp.Height * (CSng(newbmp.Width) / CSng(oldbmp.Width)))
                    ElseIf CSng(oldbmp.Width) / CSng(newsize.Width) < CSng(oldbmp.Height) / CSng(newsize.Height) Then
                        newgraphics.DrawImage(oldbmp, CSng(newbmp.Width) / 2.0F - (oldbmp.Width * (CSng(newbmp.Height) / CSng(oldbmp.Height))) / 2.0F, 0.0F, oldbmp.Width * (CSng(newbmp.Height) / CSng(oldbmp.Height)), CSng(newbmp.Height))
                    End If
    
                    newgraphics.Save()
                    newbmp.Save(MapPath(newpath), System.Drawing.Imaging.ImageFormat.Jpeg)
                    newbmp.Dispose()
                End Using
            End Using
        End Sub
      Thanks everyone!

     

    Monday, August 13, 2007 12:42 PM
  • User-1585994330 posted

     Just wanted to say thanks thats really useful! Im going to use it in a bit! John

    Tuesday, August 14, 2007 9:13 PM
  • User-1921773091 posted

     Thanks for your help Kevin!

    Thursday, August 16, 2007 6:33 PM
  • User2028632096 posted
    Does this work with animated gifs?  If not, what would it take to make it so?
    Tuesday, August 21, 2007 9:24 AM
  • User1439985827 posted

    No, it does not work with Animated GIFs. It's a little tricky, too. You have to break apart the GIF by it's frame timeline, resize each frame, and put them back together.

    Tuesday, August 21, 2007 11:56 AM
  • User751502845 posted

    Wow Kevin, thanks for your generosity in helping us out, it's appreciated.  I'm a total newbie to ASP.NET and VB.  I've tried your VB code and it works perfectly - it even keeps the aspect ratio of the original even if you specify a different aspect (the extraneous portions become white but I don't care about that).

    1) For my needs, I need to keep the original (for backup only), a "viewable" version, and a "thumbnail" version.  I can accomplish this by using your code.  I take it the most efficient thing to do is to have all the resizing done at upload time so I can have it ready to fetch and use when needed, right?  I should also store the URLs (aka paths on the server) for both the viewable and thumbnail versions in a Photo table (for example, fields - photoId, userId, thumbUrl, viewableUrl) ?

    2) And lastly..... I have a profile page for each user of my site.  On that page, I want to have a listing of all of the thumbnails for that person, and also, a viewable window for the thumbnail that is clicked on.  I'm guessing I'll use a datalist structure to list all of the thumbnails (this seems easy enough).  Now, how would I do a "master-detail" (don't know if that's the correct term) implementation, preferably in VB, where when someone clicks on a thumbnail, the viewable window gets filled with the larger version of the same photo?  How would I accomplish this without the annoying postback and the page flickering and reloading?  No child window would come up or anything - all done on one page.  I've seen this done on numerous sites (can't recall) so I know it can be done.

    TIA. [cool]

    Tuesday, August 21, 2007 4:56 PM
  • User1439985827 posted
    1. That is really up to you, how you store your images and how you figure out where they are. It depends on how you store your images, too. For instance, if your original is named original.jpg, and your thumbnail was always named original_thumb.jpg, it is safe to assume that you can get the thumbnail's directory by adding _thumb to the file name, so then you only need to store the path to the original. All in all, it's really up to you.
    2. AJAX would be a good way to do that, or when an image is clicked, it sets the src path of an img that is in a hidden DIV, then when it is clicked, it brings the DIV into view. You might want to try asking this question in another forum, such as the Web Forms Forum or the AJAX Forums, or the Client Side Development Forums.
    Thursday, August 23, 2007 9:21 AM
  • User751502845 posted

    Ahh, I see.  Thanks for your input Kevin, it's appreciated.  For #1, I'll figure out the best solution for my situation.  As for #2, seems like I gotta get up to speed on AJAX.  I thought it was just a minor add-on to ASP.NET but it seems to be a lot more than that.  I gotta get with the program hehe.  As for the master-detail I mentioned, I found another site which does this and it seems whatever he implemented, when I hover over the thumbs, I see a javascript command on the bottom status bar of IE, so either he used Javascript or something like AJAX like you mentioned (which perhaps cranks out the Javascript for you).

    Thanks again.

    Thursday, August 23, 2007 9:52 AM
  • User-1745090248 posted

    Hi Everyone,

    I can resize the image and save it, but the problem is the quality of the image become pretty bad, especially gif images.

    I have been trying this for several hours.....Anyone knows what I did wrong? Thanks in advance.

    ------------------------------------------------------------------------------------------------------------------------------------------- 

    public static void ResizeImage(Image imgToResize, int size, string ImageSavePath)
      {
       int sourceWidth = imgToResize.Width;
       int sourceHeight = imgToResize.Height;

       float nPercent = 0;
       float nPercentW = 0;
       float nPercentH = 0;

       nPercentW = ((float)size / (float)sourceWidth);
       nPercentH = ((float)size / (float)sourceHeight);

       if (nPercentH <nPercentW)
        nPercent = nPercentH;
       else
        nPercent = nPercentW;

       int destWidth = (int)(sourceWidth * nPercent);
       int destHeight = (int)(sourceHeight * nPercent);


       // Create bitmap and graphics objects for the new image
       System.Drawing.Bitmap thumbnailBitmap = new System.Drawing.Bitmap(destWidth, destHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
       System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(thumbnailBitmap);
       
       // set graphics parameters to optimize thumbnail image
       g.CompositingMode = CompositingMode.SourceOver;
       g.CompositingQuality = CompositingQuality.HighQuality;
       g.InterpolationMode = InterpolationMode.HighQualityBicubic;
       g.SmoothingMode = SmoothingMode.HighQuality;
       g.PixelOffsetMode = PixelOffsetMode.HighQuality;

       // Transform image to new size and save thumbnail
       g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
       thumbnailBitmap.Save(ImageSavePath,imgToResize.RawFormat);

       g.Dispose();
       
      }

    -----------------------------------------------------------------------------------------------------------------------------------------

    Tuesday, August 28, 2007 11:37 PM
  • User1439985827 posted

    You might need to specify the image quality when saving it. However the GIF might be a special case, I think you would have to specify a new color palette for that, which isn't easy (and I don't immediately know how to do it [:)]) However, this new code should increase the quality of JPGs and PNG images:

     

    public static void ResizeImage(Image imgToResize, int size, string ImageSavePath)
    {
    	int sourceWidth = imgToResize.Width;
    	int sourceHeight = imgToResize.Height;
    	float nPercentW = size / (float)sourceWidth;
    	float nPercentH = size / (float)sourceHeight;
    	float nPercent = (nPercentH < nPercentW) ? nPercentH : nPercentW;
    	int destWidth = (int)(sourceWidth * nPercent);
    	int destHeight = (int)(sourceHeight * nPercent);
    	using (Bitmap thumbnailBitmap = new Bitmap(destWidth, destHeight, PixelFormat.Format32bppArgb))
    	{
    		using (Graphics g = Graphics.FromImage(thumbnailBitmap))
    		{
    			g.CompositingMode = CompositingMode.SourceCopy;
    			g.CompositingQuality = CompositingQuality.HighQuality;
    			g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    			g.SmoothingMode = SmoothingMode.HighQuality;
    			g.PixelOffsetMode = PixelOffsetMode.HighQuality;
    			g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
    			Encoder qualityEncoder = Encoder.Quality;
    			EncoderParameters parameterList = new EncoderParameters(1);
    			EncoderParameter qualityParameter = new EncoderParameter(qualityEncoder, 100L);
    			parameterList.Param[0] = qualityParameter;
    			ImageCodecInfo codec = GetCodecFromExtension(Path.GetExtension(ImageSavePath));
    
    			thumbnailBitmap.Save(ImageSavePath, codec, parameterList);
    		}
    	}
    }
    
    private static ImageCodecInfo GetCodecFromExtension(string extension)
    {
    	foreach (ImageCodecInfo imageCodecInfo in ImageCodecInfo.GetImageEncoders())
    	{
    		string[] validExtensions = imageCodecInfo.FilenameExtension.Split(';');
    		if (Array.Exists<string>(validExtensions, delegate (string tomatch)
    		                                          	{
    		                                          		return String.Compare("*" + extension, tomatch, true) == 0;
    		                                          	}))
    		{
    			return imageCodecInfo;
    		}
    	}
    	return null;
    }
     
    Wednesday, August 29, 2007 6:58 PM
  • User-1745090248 posted

    Thank you VERY MUCH Kevin!

    Sorry I'm still new in C# programming, so I don't understand the code. But it doesn't matter....

    I got error message on this line of code:

    if (Array.Exists<string>(validExtensions, delegate (string tomatch)

    So sad, I can't fix it...can you help again Kevin?

    Thank you!

    Wednesday, August 29, 2007 8:11 PM
  • User1439985827 posted

    Are you using .NET 1.1 or 2.0? (Visual Studio 2003 or 2005?)

    Thursday, August 30, 2007 12:40 AM
  • User-1745090248 posted

    Are you using .NET 1.1 or 2.0? (Visual Studio 2003 or 2005?)

    1.1 and 2003 Thanks Kevin! 

     

    Thursday, August 30, 2007 1:02 AM
  • User1439985827 posted

    Give this a try: 

    public static void ResizeImage(Image imgToResize, int size, string ImageSavePath)
    {
    	int sourceWidth = imgToResize.Width;
    	int sourceHeight = imgToResize.Height;
    	float nPercentW = size / (float)sourceWidth;
    	float nPercentH = size / (float)sourceHeight;
    	float nPercent = (nPercentH < nPercentW) ? nPercentH : nPercentW;
    	int destWidth = (int)(sourceWidth * nPercent);
    	int destHeight = (int)(sourceHeight * nPercent);
    	using (Bitmap thumbnailBitmap = new Bitmap(destWidth, destHeight, PixelFormat.Format32bppArgb))
    	{
    		using (Graphics g = Graphics.FromImage(thumbnailBitmap))
    		{
    			g.CompositingMode = CompositingMode.SourceCopy;
    			g.CompositingQuality = CompositingQuality.HighQuality;
    			g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    			g.SmoothingMode = SmoothingMode.HighQuality;
    			g.PixelOffsetMode = PixelOffsetMode.HighQuality;
    			g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
    			Encoder qualityEncoder = Encoder.Quality;
    			EncoderParameters parameterList = new EncoderParameters(1);
    			EncoderParameter qualityParameter = new EncoderParameter(qualityEncoder, 100L);
    			parameterList.Param[0] = qualityParameter;
    			ImageCodecInfo codec = GetCodecFromExtension(Path.GetExtension(ImageSavePath));
    
    			thumbnailBitmap.Save(ImageSavePath, codec, parameterList);
    		}
    	}
    }
    
    private static ImageCodecInfo GetCodecFromExtension(string extension)
    {
    	foreach (ImageCodecInfo imageCodecInfo in ImageCodecInfo.GetImageEncoders())
    	{
    		string[] validExtensions = imageCodecInfo.FilenameExtension.Split(';');
    		foreach (string validExtension in validExtensions)
    		{
    			if (("*"+extension).ToLower() == validExtension.ToLower())
    			{
    				return imageCodecInfo;
    			}
    		}
    	}
    	return null;
    }
     I made the assumption you were using 2.0, but this should work for both.
    Thursday, August 30, 2007 9:31 AM
  • User-1745090248 posted

    THANK YOU Kevin! It did improve the quality!

    Thank you for your time and kindness to help me!

    For the gif images, do you have any idea how I can improve the quality too? I don't need to have animation, just static gif logo. Could you, if possible, point me a direction so that I can do some research?

    Thanks again,

    Lin

    Thursday, August 30, 2007 7:43 PM
  • User1439985827 posted

    Try looking at this article: http://www.codeproject.com/csharp/imgresizoutperfgdiplus.asp

    Monday, September 3, 2007 6:42 PM
  • User831279186 posted

    Apologies for the newb question, but I'm having trouble getting rid of the white space and allowing for higher quality jpgs on the original code.  Can anyone direct me on how to add that functionality. Here is what I have for a test so far:

     

    1    <%@ Page Language="C#" Debug="true" %>
    2    
    3    <%@ Import Namespace="System.Drawing" %>
    4    <%@ Import Namespace="System.Drawing.Drawing2D" %>
    5    <%@ Import Namespace="System.Drawing.Imaging" %>
    6    <%@ Import Namespace="System.Web" %>
    7    <%@ Import Namespace="System.Web.UI" %>
    8    <%@ Import Namespace="System.IO" %>
    9    <%@ Import Namespace="System.Data" %>
    10   <%@ Import Namespace="System.Collections" %>
    11   <%@ Import Namespace="System.Configuration" %>
    12   <%@ Import Namespace="System" %>
    13   
    14   
    15   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    16   
    17   <script runat="server">
    18       public void ResizePicture(string originalpath, string newpath, System.Drawing.Size newsize)
    19       {
    20           using (Bitmap newbmp = new Bitmap(newsize.Width, newsize.Height), oldbmp = Bitmap.FromFile(originalpath) as Bitmap)
    21           {
    22               using (Graphics newgraphics = Graphics.FromImage(newbmp))
    23               {
    24                   newgraphics.Clear(Color.FromArgb(-1));
    25                   if ((float)oldbmp.Width / (float)newsize.Width == (float)oldbmp.Height / (float)newsize.Height) //Target size has a 1:1 aspect ratio
    26                   {
    27                       newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height);
    28                   }
    29   
    30                   else if ((float)oldbmp.Width / (float)newsize.Width > (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the top and bottom
    31                   {
    32                       newgraphics.DrawImage(oldbmp, 0f, (float)newbmp.Height / 2f - (oldbmp.Height * ((float)newbmp.Width / (float)oldbmp.Width)) / 2f, (float)newbmp.Width, oldbmp.Height * ((float)newbmp.Width / (float)oldbmp.Width));
    33                   }
    34   
    35                   else if ((float)oldbmp.Width / (float)newsize.Width < (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the sides
    36                   {
    37                       newgraphics.DrawImage(oldbmp, (float)newbmp.Width / 2f - (oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height)) / 2f, 0f, oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height), (float)newbmp.Height);
    38                   }
    39   
    40                   newgraphics.Save();
    41                   newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg);
    42               }
    43           }
    44       }
    45   
    46       protected void Button1_Click(object sender, EventArgs e)
    47       {
    48           string initalPath = Server.MapPath("~/img/1.JPG").ToString();
    49           string savePath = Server.MapPath("~/imgThumb/test.jpg").ToString();
    50           System.Drawing.Size mySize = new System.Drawing.Size(400,100);
    51           
    52           ResizePicture(initalPath, savePath, mySize);
    53       }
    54   </script>
    55   
    56   <html xmlns="http://www.w3.org/1999/xhtml" >
    57   <head runat="server">
    58       <title>Untitled Page</title>
    59   </head>
    60   <body>
    61       <form id="form1" runat="server">
    62       <div>
    63           <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" /> </div>
    64       </form>
    65   </body>
    66   </html>
    
     
    Friday, January 4, 2008 7:30 AM
  • User1439985827 posted

    Sorry for the late reply. I was on vacation. [:)].

    I have a pre-built solution that demonstrates how to do this, just download the source from here: http://community.strongcoders.com/files/folders/kevins_code_samples/entry2321.aspx

    Saturday, January 12, 2008 5:58 PM
  • User1894063139 posted

     Dear Kevin,

    I amgetting an exception "A generic error occurred in GDI+" , in the line -- newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg);

     using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Imaging;

    protected void Button1_Click(object sender, EventArgs e)
        {
            string fName = FileUpload1.PostedFile.FileName.ToString();
            string newPat="D:\\anil";
            Size newSize = new Size(300, 450);
             ReSizeImage(fName, newPat, newSize);
        }

        public void ReSizeImage(string originalpath, string newpath, Size newsize)
        {
            using (Bitmap newbmp=new Bitmap(newsize.Width,newsize.Height),oldbmp=Bitmap.FromFile(originalpath) as Bitmap)
            {
                using (Graphics newgraphics=Graphics.FromImage(newbmp))
                {
                    newgraphics.Clear(Color.FromArgb(-1));
                    if ((float)oldbmp.Width / (float)newsize.Width == (float)oldbmp.Height / (float)newsize.Height) //Target size has a 1:1 aspect ratio
                    {
                        newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height);
                    }

                    else if ((float)oldbmp.Width / (float)newsize.Width > (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the top and bottom
                    {
                        newgraphics.DrawImage(oldbmp, 0f, (float)newbmp.Height / 2f - (oldbmp.Height * ((float)newbmp.Width / (float)oldbmp.Width)) / 2f, (float)newbmp.Width, oldbmp.Height * ((float)newbmp.Width / (float)oldbmp.Width));
                    }

                    else if ((float)oldbmp.Width / (float)newsize.Width < (float)oldbmp.Height / (float)newsize.Height) //There will be white space on the sides
                    {
                        newgraphics.DrawImage(oldbmp, (float)newbmp.Width / 2f - (oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height)) / 2f, 0f, oldbmp.Width * ((float)newbmp.Height / (float)oldbmp.Height), (float)newbmp.Height);
                    }

                    newgraphics.Save();
                    newgraphics.Dispose();
                    newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg);  // I am getting exception here
               }
           }
        }

    Can you helpme out to solve this ?  thanks in advance

     

     

    Saturday, November 1, 2008 1:41 AM
  • User1894063139 posted

     I am sorry Kevin, I gave the wrong path as newPath.Now its Working fine.

    This is really awesome !  Thanks a lot

     

    Saturday, November 1, 2008 2:01 AM
  • User1894063139 posted

     But some times I need to read the input image files from a url iteslf as well, instead of browsing from the local computer.

    How can i do that ? 

    Saturday, November 1, 2008 2:34 AM
  • User373202871 posted

    Dim myFile As HttpPostedFile = UploadImg.PostedFile

    Dim NewSize As System.Drawing.Size = New System.Drawing.Size(100, 100)

    ResizePictureRemoveWhiteSpace("C:\Images\sample.jpg", NewSize, myFile.InputStream)

     

    Public Sub ResizePictureRemoveWhiteSpace(ByVal newpath As String, ByVal newsize As Size, ByVal Buffer As Stream)

    Dim imgInput As Image = Image.FromStream(Buffer)

    Using oldbmp As Bitmap = CType(Bitmap.FromStream(Buffer), Image)

    If CSng(oldbmp.Width) > CSng(oldbmp.Height) Then 'landscape

    newsize.Height = oldbmp.Height / (oldbmp.Width / newsize.Width)

    ElseIf CSng(oldbmp.Height) > CSng(oldbmp.Width) Then 'portrait

    newsize.Width = oldbmp.Width / (oldbmp.Height / newsize.Height)

    ElseIf CSng(oldbmp.Width) = CSng(oldbmp.Height) Then 'square

    If newsize.Width > newsize.Height Then 'get the shortest side

    newsize.Width = newsize.Height

    Else

    newsize.Height = newsize.Width

    End If

    End If

    Using newbmp As New Bitmap(newsize.Width, newsize.Height)Using newgraphics As Graphics = Graphics.FromImage(newbmp)

    newgraphics.Clear(Color.FromArgb(-1))

    newgraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear

    newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height)

    newgraphics.Save()

    newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg)

    End Using

    End Using

    End Using

    End Sub

    Monday, January 5, 2009 10:42 PM
  • User-1460394483 posted

     

    Hi,

     

    I would like to ask you one thing. I need to resize only vertical images, I mean big ones to 273widthx171height. I am usin your code and is resizing by height  I mean never the new image fill the complete width is complete with white image the width. Do you know what would be necessary to change in the code to do this ? Thanks

     VB.NET 1.1 Yeah no problem: here you go. I tested it and it works fine. 

    Sub ResizePicture(ByRef originalpath As String, ByRef newpath As String, ByVal newsize As Size)
    Dim newbmp As New Bitmap(newsize.Width, newsize.Height), oldbmp As Bitmap = CType(Bitmap.FromFile(originalpath), Bitmap)
    Dim newgraphics As Graphics = Graphics.FromImage(newbmp)
    newgraphics.Clear(Color.FromArgb(-1))
    If CSng(oldbmp.Width) / CSng(newsize.Width) = CSng(oldbmp.Height) / CSng(newsize.Height) Then
    newgraphics.DrawImage(oldbmp, 0, 0, newsize.Width, newsize.Height)
    ElseIf CSng(oldbmp.Width) / CSng(newsize.Width) > CSng(oldbmp.Height) / CSng(newsize.Height) Then
    newgraphics.DrawImage(oldbmp, 0.0F, CSng(newbmp.Height) / 2.0F - (oldbmp.Height * (CSng(newbmp.Width) / CSng(oldbmp.Width))) / 2.0F, CSng(newbmp.Width), oldbmp.Height * (CSng(newbmp.Width) / CSng(oldbmp.Width)))
    ElseIf CSng(oldbmp.Width) / CSng(newsize.Width) < CSng(oldbmp.Height) / CSng(newsize.Height) Then
    newgraphics.DrawImage(oldbmp, CSng(newbmp.Width) / 2.0F - (oldbmp.Width * (CSng(newbmp.Height) / CSng(oldbmp.Height))) / 2.0F, 0.0F, oldbmp.Width * (CSng(newbmp.Height) / CSng(oldbmp.Height)), CSng(newbmp.Height))
    End If

    newgraphics.Save()
    newbmp.Save(newpath, System.Drawing.Imaging.ImageFormat.Jpeg)
    newgraphics.Dispose()
    oldbmp.Dispose()
    newbmp.Dispose()
    End Sub
    Thursday, January 15, 2009 6:00 AM
  • User494352855 posted

    Hey - in response to the client-side resizing-on-upload discussion; Flash Player 10 now supports local file access, and there are image compression libraries in AS3.

    However, I recommend that websites store either (1) the original images uploaded, or (2) a large version of them, say 1600x1200. Disk space is cheap, flexibility is not.

    2 years ago I built an open-source image resizing module. I tested it for a year or so, and released it on the web last summer. It's stable, mature, and has a large user base.

    You can resize any image by adding ?width=x&height=y to the URL. It's fast and very server-friendly. A LRU disk caching system is used to ensure performance and safety against denial-of-service attacks.

    It handles aspect ratio properly, and supports jpeg, png, and gif formats for both input and output. The downsampling quality was identical to photoshop in all of my tests (I guess GDI+ isn't too shabby with the right settings!).

    Monday, January 19, 2009 9:08 AM