Asked by:
Resizing and Compressing an image in asp.net

Question
-
User1463364944 posted
Hi there,
I have a requirement to do the following:
1) A user can select a gif or jpg (any size) and upload it via a standard file upload box.
On the server side I want to take the resulting file, and resize it to a fixed size (ie 640X480) and then save it to a folder for use in a flash movie, and discard the old file. Ive nveer done anything like this before in .net, any ideas where to start?
Cheers,
Justin
Monday, February 26, 2007 7:11 AM
All replies
-
User187056398 posted
You may need to do a little math to keep aspect ratios correct.//using System.Drawing; //using System.Drawing.Imaging; Bitmap OriginalBM = new Bitmap(Server.MapPath(@"~\Chrismas2004.JPG")); Size newSize = new Size(100, 100); Bitmap ResizedBM = new Bitmap(OriginalBM, newSize); ResizedBM.Save(Server.MapPath(@"~\Resized.JPG"), ImageFormat.Jpeg);
Monday, February 26, 2007 11:00 AM -
User60291871 posted
I had the same problem! Spent hours researching to try and resolve this and eventually wrote this code in VB. Works well for me, hope you find it useful.
You will need a ASPX form with a FileUpload control, a label, an image control and a button to use the code below.
Regards Sean.
Imports
System.IO Imports System.Drawing Partial Class _DefaultInherits System.Web.UI.Page
Protected Sub btnUpload_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnUpload.Click
Const bmpW = 300 'New image target width
Const bmpH = 226 'New Image target height
If (FileUpload1.HasFile) Then'Clear the error label text
lblError.Text = ""
'Check to make sure the file to upload has a picture file format extention and set the target width and height
If (CheckFileType(FileUpload1.FileName)) Then
Dim newWidth As Integer = bmpW
Dim newHeight As Integer = bmpH
'Use the uploaded filename for saving without the '.' extension
Dim upName As String = Mid(FileUpload1.FileName, 1, (InStr(FileUpload1.FileName, ".") - 1))
'Set the save path of the resized image, you will need this directory already created in your web site
Dim filePath As String = "~/Upload/" & upName & ".png"
'Create a new Bitmap using the uploaded picture as a Stream
'Set the new bitmap resolution to 72 pixels per inch
Dim upBmp As Bitmap = Bitmap.FromStream(FileUpload1.PostedFile.InputStream)
Dim newBmp As Bitmap = New Bitmap(newWidth, newHeight, Imaging.PixelFormat.Format24bppRgb)
newBmp.SetResolution(72, 72)
'Get the uploaded image width and height
Dim upWidth As Integer = upBmp.Width
Dim upHeight As Integer = upBmp.Height
Dim newX As Integer = 0 'Set the new top left drawing position on the image canvas
Dim newY As Integer = 0
Dim reDuce As Decimal
'Keep the aspect ratio of image the same if not 4:3 and work out the newX and newY positions
'to ensure the image is always in the centre of the canvas vertically and horizontally
If upWidth > upHeight Then 'Landscape picture
reDuce = newWidth / upWidth
'calculate the width percentage reduction as decimal
newHeight = Int(upHeight * reDuce)
'reduce the uploaded image height by the reduce amount
newY = Int((bmpH - newHeight) / 2)
'Position the image centrally down the canvas
newX = 0 'Picture will be full width
ElseIf upWidth < upHeight Then 'Portrait picture
reDuce = newHeight / upHeight
'calculate the height percentage reduction as decimal
newWidth = Int(upWidth * reDuce)
'reduce the uploaded image height by the reduce amount
newX = Int((bmpW - newWidth) / 2)
'Position the image centrally across the canvas
newY = 0 'Picture will be full hieght
ElseIf upWidth = upHeight Then 'square picture
reDuce = newHeight / upHeight
'calculate the height percentage reduction as decimal
newWidth = Int(upWidth * reDuce)
'reduce the uploaded image height by the reduce amount
newX = Int((bmpW - newWidth) / 2) 'Position the image centrally across the canvas
newY = Int((bmpH - newHeight) / 2) 'Position the image centrally down the canvas
End If
'Create a new image from the uploaded picture using the Graphics class
'Clear the graphic and set the background colour to white
'Use Antialias and High Quality Bicubic to maintain a good quality picture
'Save the new bitmap image using 'Png' picture format and the calculated canvas positioning
Dim newGraphic As Graphics = Graphics.FromImage(newBmp)
Try
newGraphic.Clear(Color.White)
newGraphic.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
newGraphic.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
newGraphic.DrawImage(upBmp, newX, newY, newWidth, newHeight)
newBmp.Save(MapPath(filePath), Imaging.ImageFormat.Png)
'Show the uploaded resized picture in the image control
Image1.ImageUrl = filePath
Image1.Visible = True
Catch ex As Exception
lblError.Text = ex.ToString
Finally
upBmp.Dispose()
newBmp.Dispose()
newGraphic.Dispose()
End Try
Else
lblError.Text = "Please select a picture with a file format extension of either Bmp, Jpg, Jpeg, Gif or Png."
End If
End If
End Sub
Function CheckFileType(ByVal fileName As String) As Boolean
Dim ext As String = Path.GetExtension(fileName)
Select Case ext.ToLower()
Case ".gif"
Return True
Case ".png"
Return True
Case ".jpg"
Return True
Case ".jpeg"
Return True
Case ".bmp"
Return True
Case Else
Return False
End Select
End Function
End
Class
Monday, March 12, 2007 4:47 AM -
User1075616431 posted
smcoxon I love you! BRILLIANT BRILLIANT!! lol
Amazing code!
Monday, April 30, 2007 4:25 PM -
User1075616431 posted
smcoxon I love you! BRILLIANT BRILLIANT!! lol
Amazing code!HOLY
SHITMonday, April 30, 2007 4:25 PM -
User60291871 posted
Glad you liked it!
Have fun [:)]
Saturday, May 5, 2007 12:35 PM -
User60291871 posted
Glad you liked it!
Have fun [:)]
Saturday, May 5, 2007 12:36 PM -
User1075616431 posted
The triple post was an accident... I have a mouse that causes uncontrolled postbacks! lol
Monday, May 7, 2007 1:54 AM -
User60291871 posted
Funny the same happened to me! I didn't mean to send you two replies, honest.
Have fun.
Smcoxon
Monday, May 7, 2007 4:16 PM -
User1947866343 posted
Great post, thanks! [:D]
I needed unique file names as we have many files that get uploaded and don't want anyone to overwrite another. So I changed this:
Dim upName As String = Mid(FileUpload1.FileName, 1, (InStr(FileUpload1.FileName, ".") - 1))
To this:
Dim upName As String = DateTime.UtcNow.Ticks
Basically changes the name of the file to a timestamp to keep it unique.Thursday, May 17, 2007 4:09 PM -
User1947866343 posted
I also decided to use a CustomFieldValidator to check the file extension instead of labels because I'm using a FormView for updating user information. Here's the validator if anyone is interested:
Protected Sub custfupImage_Validate(ByVal sender As Object, ByVal args As ServerValidateEventArgs) Dim fupImage As FileUpload = Me.fvUserInfo.FindControl("fupImage") If fupImage.HasFile Then Dim ext As String = Path.GetExtension(fupImage.FileName) Select Case ext.ToLower() Case ".gif" args.IsValid = True Case ".png" args.IsValid = True Case ".jpg" args.IsValid = True Case ".jpeg" args.IsValid = True Case ".bmp" args.IsValid = True Case Else args.IsValid = False End Select End If End Sub
Thursday, May 17, 2007 5:17 PM -
User60291871 posted
I've changed the CheckFileType function in my original code to also check the MIME type to ensure the file extention matches the file MIME type. Just in case someome tries to upload some bad code in a text file hidden as a picture file.
Function CheckFileType(ByVal fileName As String, ByVal MimeType As String) As Boolean Dim ext As String = Path.GetExtension(fileName) Select Case ext.ToLower() Case ".gif" If MimeType.ToLower = "image/gif" Then Return True Else Return False End If Case ".png" If MimeType.ToLower = "image/png" Then Return True ElseIf MimeType.ToLower = "image/x-png" Then Return True Else Return False End If Case ".jpg" If MimeType.ToLower = "image/jpeg" Then Return True ElseIf MimeType.ToLower = "image/pjpeg" Then Return True Else Return False End If Case ".jpeg" If MimeType.ToLower = "image/jpeg" Then Return True ElseIf MimeType.ToLower = "image/pjpeg" Then Return True Else Return False End If Case ".bmp" If MimeType.ToLower = "image/bmp" Then Return True Else Return False End If Case Else Return False End Select End Function
Thursday, May 17, 2007 6:37 PM -
User60291871 posted
PS. Forgot to say you also ned to change the If statement that calls the CheckFileType function to:
If CheckFileType(Upload.FileName, Upload.PostedFile.ContentType) Then
Thursday, May 17, 2007 6:41 PM -
User1075616431 posted
aha, I'll try that.
Made a few changes too, made it into a sub taking width and height as parameters too..
Friday, May 18, 2007 1:38 AM -
User1947866343 posted
Nice touch, thanks!
Friday, May 18, 2007 9:09 AM -
-
User60291871 posted
Hi, I haven't tested this but give it a try. In the lines of code, add a line under the line that sets the newBmp resolution to set the newBmp palette to the palette of the uploaded file:
newBmp.Palette = upBmp.Palette
In the lines that set the newGraphic canvas color to white and smoothing mode to AntiAlias, change it to Transparent and smoothingMode to None. I.e.
newGraphic.Clear(Color.White) newGraphic.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
change to:
newGraphic.Clear(Color.Transparent) newGraphic.SmoothingMode = Drawing2D.SmoothingMode.None
Friday, June 8, 2007 1:59 PM -
User-1193497391 posted
Thanks for the answer smcoxon It didn't work as expected though - because apparently it requores rocket science to resizing GIF in GDI+ while preserving transparency and almost-original color palette science.
Luckily - if someone ever needs this functionality - the solution has been encapsulated here http://codebetter.com/blogs/brendan.tompkins/archive/2004/01/26/6103.aspxFriday, June 8, 2007 4:20 PM -
User1947866343 posted
Very nice...thanks for the link!
Friday, June 8, 2007 4:30 PM -
User60291871 posted
Thanks for this - useful article.
Saturday, June 9, 2007 7:56 AM -
User1075616431 posted
Is it possible to have a transparent background instead of the white stripes?
Monday, June 11, 2007 1:22 AM -
User60291871 posted
Hi, Yes should not be a problem. Just change the line that sets the canvas coloor to white - to transparent.
newGraphic.Clear(Color.Transparent)
Friday, June 15, 2007 2:16 PM -
User402855335 posted
Hi There,
I have just found this code and tryed it out and I am having a few problems with the input control's properties. At the beginning of your code you set fileupload1's "hasfile" and "filename" properties.
I copied the code into a new web app ( VS 2003, I also tryed VS 2005 - same problem), added the controls as you said. I then set the file upload control...
Protected
WithEvents FileUpload1 As System.Web.UI.HtmlControls.HtmlInputFileYet when I looked at the code the properties "Hasfile" and "Filename" are not assosiated or available as you had shown in your code.
Am I wrong in setting the with events statement to ...htmlinputfile???
Or is there any other issues that I should be aware of?
Thanks,
Simon
Tuesday, October 23, 2007 4:37 AM -
User60291871 posted
Hi Simon,
From your post I'm not sure what you are tring to do? In my code the properties of the FileUpload1 control are read and used by code within the btnUpload_Click event. The namespace for the control is: System.Web.UI.WebControls. Also take a lok at: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.fileupload(VS.80).aspx
Wednesday, October 24, 2007 4:08 PM -
User-1136638018 posted
thanks, here is the same code but coded in C#.
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
private Boolean CheckFileType(String fileName)
{
String ext = Path.GetExtension(fileName) ;switch (ext.ToLower())
{
case ".gif":
return true;
case ".png":
return true;
case ".jpg":
return true;
case ".jpeg":
return true;
case ".bmp":
return true;
default:
return false;
}
}protected void Button1_Click(object sender, EventArgs e)
{
const int bmpW = 300;// //New image target width
const int bmpH = 226;// //New Image target heightif (FileUpload1.HasFile)
{
//Clear the error label text
lblError.Text = "";//Check to make sure the file to upload has a picture file format extention
//and set the target width and heightif (this.CheckFileType(FileUpload1.FileName))
{
Int32 newWidth = bmpW;Int32 newHeight = bmpH;
//Use the uploaded filename for saving without the "." extension
String upName = FileUpload1.FileName.Substring(0, FileUpload1.FileName.IndexOf("."));
//Mid(FileUpload1.FileName, 1, (InStr(FileUpload1.FileName, ".") - 1)) ;//Set the save path of the resized image, you will need this directory already created in your web site
String filePath = "~/Upload/" + upName + ".jpg";
//Create a new Bitmap using the uploaded picture as a Stream
//Set the new bitmap resolution to 72 pixels per inchBitmap upBmp = (Bitmap)Bitmap.FromStream(FileUpload1.PostedFile.InputStream);
Bitmap newBmp = new Bitmap(newWidth, newHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
newBmp.SetResolution(72, 72);
//Get the uploaded image width and height
Int32 upWidth = upBmp.Width;
Int32 upHeight = upBmp.Height;
Int32 newX = 0; //Set the new top left drawing position on the image canvas
Int32 newY = 0;
Decimal reDuce;
//Keep the aspect ratio of image the same if not 4:3 and work out the newX and newY positions
//to ensure the image is always in the centre of the canvas vertically and horizontallyif (upWidth > upHeight)
{
//Landscape picturereDuce = newWidth / upWidth;
//calculate the width percentage reduction as decimal
newHeight = ((Int32)(upHeight * reDuce));
//reduce the uploaded image height by the reduce amount
newY = ((Int32)((bmpH - newHeight) / 2));
//Position the image centrally down the canvas
newX = 0; //Picture will be full width
}
else
{
if (upWidth < upHeight)
{
//Portrait picturereDuce = newHeight / upHeight;
//calculate the height percentage reduction as decimal
newWidth = ((Int32)(upWidth * reDuce));
//reduce the uploaded image height by the reduce amount
newX = ((Int32)((bmpW - newWidth) / 2));
//Position the image centrally across the canvas
newY = 0; //Picture will be full hieght
}
else
{
if (upWidth == upHeight)
{
//square picturereDuce = newHeight / upHeight;
//calculate the height percentage reduction as decimal
newWidth = ((Int32)((upWidth * reDuce)));
//reduce the uploaded image height by the reduce amount
newX = ((Int32)(((bmpW - newWidth) / 2))); //Position the image centrally across the canvas
newY = ((Int32)(((bmpH - newHeight) / 2))); //Position the image centrally down the canvas
}
}
}//Create a new image from the uploaded picture using the Graphics class
//Clear the graphic and set the background colour to white
//Use Antialias and High Quality Bicubic to maintain a good quality picture
//Save the new bitmap image using //Png// picture format and the calculated canvas positioning
Graphics newGraphic = Graphics.FromImage(newBmp);
try
{
newGraphic.Clear(Color.White);newGraphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
newGraphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
newGraphic.DrawImage(upBmp, newX, newY, newWidth, newHeight);
newBmp.Save(MapPath(filePath), System.Drawing.Imaging.ImageFormat.Jpeg);
//Show the uploaded resized picture in the image control
Image1.ImageUrl = filePath;
Image1.Visible = true;
}
catch (Exception ex)
{
lblError.Text = ex.ToString();
throw ex;
}
finally
{
upBmp.Dispose();newBmp.Dispose();
newGraphic.Dispose();
}
}
else
{
lblError.Text = "Please select a picture with a file format extension of either Bmp, Jpg, Jpeg, Gif or Png.";}
}
}}
Wednesday, November 7, 2007 10:23 AM -
User-551833813 posted
Hi friends,
I was trying to use your code to resize users uploaded images to a small size as Avatar images for a website forum.I think the width and height for this purpose is big.I tried using 100 * 100 as bitmap width and height but the image doesn't appear(even it realy exists.I checked that using the mouse right click).Could you help me to solve this problem?.
Monday, May 26, 2008 4:55 AM -
User60291871 posted
Hi,
Are you using the VB or C# version of my code? I know the VB version works but not being a C# person I can't say the same for the C# version as someone else converted my code to C# and posted it here. No reason why it shouldn't work though.
Does the image appear if you set the width and height to a larger size? Have you tried doing a browser refresh after the code has run to see if the picture is dispalyed after a refresh? Is the image file saved as expected in your images directory and can you open and view/edit it using a graphics (paintbrush) application?
One other thing to note, most pictures have a 4:3 aspect ratio. Therefore, I'd change your width/height constants to 100 x 75.
Monday, May 26, 2008 7:35 AM -
User-551833813 posted
Thank you for your respond.I used the C# code.The images are saved in the specified folder but as a white image in the correct size.The size I specified was 100 * 100.When I changed the size to 300 * 200 it does the same with jpg images(white images again) but when I try it with a .gif image it works but the result image size was 417*226.
Monday, May 26, 2008 7:59 AM -
User60291871 posted
Hi,
I decided to re-create my code in C# as you are the second person who has had this blank image problem with the C# code previously posted. I've tested it out and it works fine, even with the bmpW and bmpH, width and Height constants, both set to 100. Basically the problem in the C# code was with the data types used for the Reduce, UpWidth and UpHeight variables, resulting in a Reduce variable value of 0 most of the time. Here's the working C# code:
using System; using System.IO; using System.Drawing; public partial class _Default : System.Web.UI.Page { public bool CheckFileType(string fileName) { string ext = Path.GetExtension(fileName); switch (ext.ToLower()) { case ".gif": return true; case ".png": return true; case ".jpg": return true; case ".jpeg": return true; case ".bmp": return true; default: return false; } } protected void btnUpload_Click(object sender, EventArgs e) { const int bmpW = 300; //New image target width const int bmpH = 225; //New Image target height if ((FileUpload1.HasFile)) { //Clear the error label text lblError.Text = ""; //Check to make sure the file to upload has a picture file format extention and set the target width and height if ((CheckFileType(FileUpload1.FileName))) { Int32 newWidth = bmpW; Int32 newHeight = bmpH; //Use the uploaded filename for saving without the '.' extension String upName = FileUpload1.FileName.Substring(0, FileUpload1.FileName.IndexOf(".")); //Set the save path of the resized image, you will need this directory already created in your web site string filePath = "~/Upload/" + upName + ".jpg"; //Create a new Bitmap using the uploaded picture as a Stream //Set the new bitmap resolution to 72 pixels per inch Bitmap upBmp = (Bitmap)Bitmap.FromStream(FileUpload1.PostedFile.InputStream); Bitmap newBmp = new Bitmap(newWidth, newHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb); newBmp.SetResolution(72, 72); //Get the uploaded image width and height Double upWidth = upBmp.Width; Double upHeight = upBmp.Height; int newX = 0; //Set the new top left drawing position on the image canvas int newY = 0; Double reDuce; //Keep the aspect ratio of image the same if not 4:3 and work out the newX and newY positions //to ensure the image is always in the centre of the canvas vertically and horizontally if (upWidth > upHeight) { //Landscape picture reDuce = newWidth / upWidth; //calculate the width percentage reduction as decimal newHeight = ((Int32)(upHeight * reDuce)); //reduce the uploaded image height by the reduce amount newY = ((Int32)((bmpH - newHeight) / 2)); //Position the image centrally down the canvas newX = 0; //Picture will be full width } else if (upWidth < upHeight) { //Portrait picture reDuce = newHeight / upHeight; //calculate the height percentage reduction as decimal newWidth = ((Int32)(upWidth * reDuce)); //reduce the uploaded image height by the reduce amount newX = ((Int32)((bmpW - newWidth) / 2)); //Position the image centrally across the canvas newY = 0; //Picture will be full hieght } else if (upWidth == upHeight) { //square picture reDuce = newHeight / upHeight; //calculate the height percentage reduction as decimal newWidth = ((Int32)(upWidth * reDuce)); //reduce the uploaded image height by the reduce amount newX = ((Int32)((bmpW - newWidth) / 2)); //Position the image centrally across the canvas newY = ((Int32)((bmpH - newHeight) / 2)); //Position the image centrally down the canvas } //Create a new image from the uploaded picture using the Graphics class //Clear the graphic and set the background colour to white //Use Antialias and High Quality Bicubic to maintain a good quality picture //Save the new bitmap image using 'Png' picture format and the calculated canvas positioning Graphics newGraphic = Graphics.FromImage(newBmp); try { newGraphic.Clear(Color.White); newGraphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; newGraphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; newGraphic.DrawImage(upBmp, newX, newY, newWidth, newHeight); newBmp.Save(MapPath(filePath), System.Drawing.Imaging.ImageFormat.Jpeg); //Show the uploaded resized picture in the image control Image1.ImageUrl = filePath; Image1.Visible = true; } catch (Exception ex) { string newError = ex.Message; lblError.Text = newError; } finally { upBmp.Dispose(); newBmp.Dispose(); newGraphic.Dispose(); } } else { lblError.Text = "Please select a picture with a file format extension of either Bmp, Jpg, Jpeg, Gif or Png."; } } } }
Monday, May 26, 2008 4:21 PM -
User-551833813 posted
It works perfectly thank you very much...[:D]
Tuesday, May 27, 2008 5:16 AM -
User60291871 posted
Hi TheEagle, in all the replies I have posted on this topic, nobody has marked any of them as answers. Would you be kind enough to do so for me please?<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p> Thanks
smcoxon<o:p></o:p>Thursday, June 5, 2008 5:56 AM -
User1075616431 posted
I would mark several of them, but the option isn't there...
I've used this a bit, and changed the code little by little, in each app.
But even the code from your first post worked.
again, GJ & TY, smcoxon!!
Friday, June 6, 2008 1:45 AM -
User60291871 posted
That explains it. Of course, the person who asked the very first question has the key to answer, nobody else. Thanks you for letting me know NNM and for showing your appreciation.
Friday, June 6, 2008 1:40 PM -
User-1412983413 posted
Monday, June 9, 2008 2:33 PM -
User60291871 posted
Your welcome. Glad it helped you out.
Monday, June 9, 2008 5:10 PM -
User589874384 posted
hi
ive stumbled upon this thread in the hopes of figuring out how to resize an image that came from a URL. i didnt upload any images but i just retrieved the image's link and i want to resize it to my desired resolution. ive read the String upName = FileUpload1.FileName.Substring(0, FileUpload1.FileName.IndexOf(".")); line and it seemed to be the code to get the file but how do i work around this with an image fetched from another site?
Sunday, November 16, 2008 10:50 PM -
User60291871 posted
Hi,
I've never tried to do this and I'm not sure how you'd go about downloading an image displayed on another web site. However, take a look at the links below, they may give you some pointers.
http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx
http://bytes.com/forum/thread235707.html
http://forums.asp.net/p/1318641/2614961.aspx#2614961Tuesday, November 18, 2008 9:07 AM -
User589874384 posted
actually, i have a working program already but it calls another code to download the pictures before resizing it.
also, is there a way to have Bitmap make its own canvass off of an image from another website/url?
Tuesday, November 18, 2008 11:14 PM