Click here to Skip to main content
Click here to Skip to main content

Simple Image Resizing Library

, 18 Jan 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
A simple library to manage and resize uploaded images.

Introduction

I seem to be doing a lot of applications where I have to deal with images a lot, and specifically the issue of dynamically resizing images - so I decided to write a library to make the process as simple as possible.

Background

My goals for this library were to make it easy to use, and flexible enough to be used no matter how you store your images (FileSystem, Database, Amazon Web Services, etc.). As for the discussion on which way is the "best" way to store images, I'll leave that to someone else. However, anyway you go, there's still some common things you have to think about: resizing images and maintaining aspect ratio, uniqueness of file names, etc.

Using the code

I usually try not to add extra objects when creating simple libraries like this one - but in this case, I thought it might actually help. To resize images, sometimes a lot of information is needed: the image stream, content type, desired width or height, etc. So, rather than create methods with a ton of parameters, this library will use the ImageInfo object which holds most of this information for us. I've also split some methods up into two "manager" classes: WebManager and FileManager. If you're using this library on a code-behind page, then the "WebManager" object is probably the best way to go - otherwise you'd use the "FileManager" class.

Best of all, you can override or inherit from just about anything, so you can modify it to fit your specific situation.

The attached demo project includes all the samples described here, as well as a separate project containing the library.

Sample: Save an uploaded image and resized versions

In this first example, we'll assume that we've just posted an ASPX page, and used a FileUpload control to select an image to upload. This code is placed in the ButtonSubmit_Click method:

//use WebManager to get the file, and save it
IImageInfo img = WebManager.GetImageInfo(fileUploader);
img.Path = "uploadedImages";
img.Save();
    
//now create resized versions, and save them
IImageInfo imgLarge = img.ResizeMe(null, 300);    //constrain to 300 pixels wide
imgLarge.Save("uploadedImages/large");        //save file in a folder named "large"
    
IImageInfo imgMedium = img.ResizeMe(185, null);    //constrain to 185 pixels high
imgMedium.Save("uploadedImages/medium");

IImageInfo imgSmall = img.ResizeMe(null, 100);    //constrain to 100 pixels wide
imgSmall.Save("uploadedImages/small");

IImageInfo imgTiny = img.ResizeMe(50, null);    //constrain to 50 pixels high
imgTiny.Save("uploadedImages/tiny");

Let's go over the example above, line by line. The first line calls the static GetImageInfo method on the WebManager class. This method takes the FileUpload, populates an object that uses the IImageInfo interface with the information of the uploaded image, and returns it.

IImageInfo img = WebManager.GetImageInfo(fileUploader);

The next line sets the Path to the directory "uploadedImages". This is the directory that we want to save the original uploaded file into. **Please note that you must adjust the permissions on this directory to allow the .NET process to write to it. In my case, I have given "modify" privileges to three users: IIS_WPG, ASPNET, and IIS_IUSRS.

img.Path = "uploadedImages";

The next line simply calls the Save method that is available on the ImageInfo object. Because we didn't pass in any parameters, this method will save the uploaded image using its existing file name.

img.Save();

The next line uses the ResizeMe method available on the ImageInfo class to resize the image it holds, and then returns a new ImageInfo object with the resized image. The ImageInfo object contains all of the same information as the original image (path, filename, etc), but the PhotoStream, Width, and Height are set to the resized image dimensions. The ResizeMe method takes two nullable integers: maxHeight and maxWidth. In this case, we only care about the width being 300 pixels - so we can set maxHeight to null (or 0). Setting both the maxHeight and maxWidth parameters would resize the image so that neither the maxHeight nor maxWidth was exceeded. It would not resize the image to the exact maxHeight and maxWidth specified - it would still maintain the correct aspect ratio. In the example below, we pass in null for the maxHeight, and 300 for the width, resulting in an image resized with a width of 300 pixels.

IImageInfo imgLarge = img.ResizeMe(null, 300);

The next line calls the Save method again, but this time, we pass in the path that we want to save the image to. In this case, we want the resized image to reside in the "uploadedImages/large" directory.

imgLarge.Save("uploadedImages/large");

(**Note: We could also prepend "/large" to the existing Path property of the imgLarge variable as shown below, and then call Save()):

imgLarge.Path += "/large";

The next section does the same resize action shown above, but this time resizes the image by setting a maxHeight, and no maxWidth.

IImageInfo imgMedium = img.ResizeMe(185, null);
imgMedium.Save("uploadedImages/medium");

So, that's the bare bones example. However, you're not always going to save images in this way; many times, they need to be tied to specific records in a database, or be named in a specific way. Let's take a look at what we might do in some other situations.

Other examples

In the following code sample, we'll save a pointer to an image in the database first, then use the new ID in the image filename.

//get uploaded image
IImageInfo img = WebManager.GetImageInfo(fileUploader);
string[] fileNameParts = img.FileName.split('.');
string fileExtension = fileNameParts.GetValue((fileNameParts.Length - 1));

Photo p = new Photo();
p.ProductID = 1;    //tie it to a product
p.Path = "uploadedImages/photos";
p.Description = "Left side view";
p.FileExtension = fileExtension;
ProductRepository.Save(p);

int newID = p.PhotoID;

img.Path = p.Path;
img.FileName = string.Format("{0}.{1}", newID.ToString(), p.FileExtension);
img.Save();

//save thumbnail versions
img.ResizeMe(null, 185).Save(p.Path += "/large");
img.ResizeMe(null, 100).Save(p.Path += "/medium");
img.ResizeMe(null, 50).Save(p.Path += "/small");

The above sample shows how this library makes things a bit easier when saving product photos. In it, we save the record to the database first, then save the images to the file system using the unique ID generated when the record was created. Now, when we need to display this product photo, we can simply point to the "uploadedImages/photos/[PhotoID].[FileExtension]" file. If the smaller image is needed, simply point to the image under the "large", "medium", or "small" subfolder.

So, given the sample above, what happens if we need to delete a pPhoto? It'd be nice to delete the original image from the file system as well as all the thumbnail images that were generated. Luckily, we can do that a couple different ways. To delete the images that were created in the example above, you would do something like this:

Photo p = PhotoRepository.GetPhotoByID(id);

//first, delete the images
string[] pathsToDeleteFrom = new string[] { p.Path, p.Path += 
  "/large", p.Path += "/medium", p.Path += "/small" };
WebManager.DeleteImageSetFromFileSystem(string.Format("{0}.{1}", 
  p.PhotoID.ToString(), p.FileExtension), pathsToDeleteFrom);

//now delete the database record
PhotoRepository.Delete(p);

The DeleteImageSetFromFileSystem method takes in the filename and the string array of paths (directories) to delete that file from. So, in this example, the filename with this photo's PhotoID will be deleted from each of the paths in the string array.

Conclusion

So, that's a quick look at the library. I hope you find it useful. I hope to update with more features in the future, and will post those here when I do.

Any feedback/suggestions are definitely welcome!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Leftend
Software Developer (Senior) Leftend
United States United States
No Biography provided

Comments and Discussions

 
Questionphoto PinmemberLouwerenslodder8-Jan-14 10:14 
GeneralMy vote of 5 PinmemberJenni Osborn19-Jan-12 1:19 
QuestionSee imageresizing.net instead PinmemberNathanael Jones6-Jan-12 7:43 
GeneralObject reference not set to an instance of an object Pinmemberavigalim200014-May-11 6:22 
GeneralThanks! PinmemberRkHrd30-Jan-10 9:18 
GeneralImage or Blob Resizing PinmemberSP Vilakazi1-Oct-09 8:36 
GeneralVC6 & Simple Image Resizing Library Pinmemberandwan07-Jun-09 8:10 
GeneralRe: VC6 & Simple Image Resizing Library PinmemberLeftend8-Jun-09 8:08 
Generalabout dynamics,, Pinmemberykorotia18-Jan-09 4:04 
GeneralRe: about dynamics,, PinmemberLeftend18-Jan-09 11:38 
JokeRe: about dynamics,, Pinmemberykorotia18-Jan-09 12:29 
GeneralNice Job! PinmemberHampden Tech10-Jan-09 5:23 
GeneralMy vote of 1 Pinmemberezeew6-Jan-09 13:17 
GeneralRe: My vote of 1 Pinmemberykorotia18-Jan-09 12:32 
GeneralGood Job PinmemberAshok Bhawar30-Sep-08 15:37 
QuestionSetting JPG Quality PinmemberGrZeCh198322-Jul-08 2:16 
GeneralRe: Setting JPG Quality PinmemberGrZeCh198322-Jul-08 2:18 
AnswerRe: Setting JPG Quality PinmemberGrZeCh198322-Jul-08 3:22 
QuestionExcellent Component PinmemberThe Womble16-Mar-08 14:24 
QuestionImage Quality PinmemberMember 401139728-Feb-08 11:49 
GeneralRe: Image Quality PinmvpChristian Graus28-Feb-08 12:26 
Generalsaves a lot PinmemberRiad MS Afyouni16-Feb-08 22:42 
GeneralGreat Job Pinmembermerlin98121-Jan-08 5:02 
GeneralRe: Great Job PinmemberLeftend21-Jan-08 6:32 
GeneralGood one Pinmembertkjbbs20-Jan-08 21:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.1411028.1 | Last Updated 18 Jan 2008
Article Copyright 2008 by Leftend
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid