Server-side Image Resizing Module for ASP.NET, ASP, & PHP/IIS
Download trial
Includes v2.1b – Nov 13, 2009
Purchase securely using Paypal, Visa, MasterCard, Discover, or American Express.
ChangelogLicenseSamplesInstallation
If you have any questions after reading the documentation, leave a comment or e-mail nathanael.jones@gmail.com.
You need this module if you work with images.
Once installed, you can size, crop, and change the format of images from anywhere… HTML, ASP.NET, ASP, PHP, Flex, or Flash … Just add the desired behavior to the URL with “?width=100″ or “?format=jpg”. It supports scaling, cropping, rotating, flipping, stretching, padding, borders, transparency, jpeg, png, and gif formats. Aspect ratio is always maintained unless &stretch=fill is specified.
Server-side image resizing is one of those little features that can have incredible ROI. It can save webmasters several hours each day, and gives you the ability to change the resolution of an image without having to hunt up the original.
I developed this image resizing system around two years ago. I needed something very intuitive, simple, secure, and efficient. We’ve been using this system heavily on a live, high-traffic site (youngfoundations.org) for two years, and we have had zero stability problems, memory leaks, or reliability issues with it. It’s very mature and stable. Version 2.0 is even faster and more scalable than the previous versions, and includes dozens of new features.
The difference between the actual size and wanted size of an uploaded image is inversely proportional to the quantiy of time available and the sluggishness of Photoshop.
Check out the samples page to see what it can do. The license is much like the GPL, and allows you to redistribute the source code as part of a larger project. You’ll find the source code very clean, organized, and well commented.
Although I typically release my components for free, I decided to charge a ‘download fee’ for this one to help support my other open-source projects. Don’t worry, this component is still open-source, and the license permits source redistribution as part of a larger system. However, I’m asking that people who want to integrate this component purchase the download instead of ripping it out of another open-source project. My free to non-free LOC (lines of code) ratio is still over 40 to 1, and I plan on keeping it that way. I trust this will keep everybody happy.
Your donations are the reason Version 2 exists.
A few user comments…
Querystring-based resizing is super-simple and can be used from any language (HTML, ASP.NET, PHP, Flash, Flex, etc).
Supports scaling, cropping, rotating, flipping, stretching, padding, borders, transparency, and the 4 main image formats. Aspect ratio is maintained unless &stretch=fill is specified.
For example, to make an image 400px or less wide, just add ?width=400. If you want to set both the maximum height and width, use ?maxwidth=400&maxheight=400.
Sometimes you need all your images to be exactly the same size, regardless of the original aspect ratio. There are several solutions to this. If you specify both width and height, whitespace will be automatically added to two sides to make up the difference. Set whitespace color with &bgcolor. If you don’t want whitespace, you can try &crop=auto. This “smart cropping” will figure out the minimal amount of cropping needed to center the image in the box without changing the aspect ratio or leaving whitespace. And, of course, you could stretch your images with &stretch=fill… if you really wanted to.
Convert between jpg, png, gif, tiff, and bmp images with &format=jpg|png|gif. Adjust the quality/size tradeoff of Jpegs with &quality=1-100, and the palette size of GIFs and PNGs with &colors=2-255
Not just for thumbnails – useful for resizing entire slideshows in real-time as the user changes the window size.
You can select any frame of an animated GIF with ?frame=x, and any page from a TIFF file with ?page=x.
Manually crop out parts of an image with ?crop=(x1,y1,x2,y2). Rotate with ?rotate=degrees. Flip with ?flip=h|v|both.
And the best part – add borders and paddings without causing CSS layout bugs!
Check out the samples page to see all the features in action.
- Supported input formats: BMP, GIF, JPG, PNG and TIFF
- Supported output formats: JPG, PNG, and GIF
Command Reference
- width, height – force the width and/or height to certain dimensions. Whitespace will be added if the aspect ratio is different.
- maxwidth, maxheight – fit the image within the specified bounds. (Most often used)
- crop=auto – Crop the image the the size specified by width and height. Centers and minimally crops to preserve aspect ratio.
- crop=(x1,y1,x2,y2) – Crop the image to the specified rectangle on the source image. You can use negative coordinates to specifiy bottom-right relative locations.
- rotate=degress – Rotate the image.
- bgcolor=color name| hex code (6-char). Sets the background/whitespace color.
- stretch=fill – Stretches the image to width and height if both are specified. This is the only way to lose aspect ratio.
- scale=both|upscaleonly|downscaleonly – By default, images are never upscaled. Use &scale=both to grow an image.
- flip=h|v|both – Flips the image after resizing.
- sourceFlip=h|v|both – Flips the source image before resizing/rotation.
- paddingWidth=px & paddingColor=color|hex. paddingColor defaults to bgcolor, which defaults to white.
- borderWidth=px, borderColor=color|hex.
- format=jpg|png|gif
- colors=2-255 – Control the palette size of PNG and GIF images. If omitted, PNGs will be 24-bit.
- frame=x – Choose which frame of an animated GIF to display.
- page=x – Choose which page of a multi-page TIFF document to display.
Bicubic resampling is used exclusively, resulting in very high-quality output. Jpeg compression is excellent, and uses the native windows JPEG encoder. Version 2.0 adds octree quantization for GIF and 8-bit PNG output, providing excellent palette generation for those also.
In my tests, the native windows JPEG encoder and Photoshop have the same visual quality and file size results. Expect photoshop-quality results for both JPEG and PNG output.
GIF and 8-bit PNG output is drastically improved in version 2.0 due to the addition of octree quantization. The primary difference you will notice between Photoshop and module output is the lack of dithering. In most scenarios this doesn’t affect visual quality much and actually makes the image look ‘cleaner’. Very gentle gradients do benefit from dithering, as do gradients against transparency.
File sizes are excellent – don’t expect a measurable improvement when you use Photoshop or ImageReady to compress your images with the same quality settings.
The key to the excellent performance of this module is the disk caching system. This allows even a relatively low-end server to handle the same number of dynamic requests as static file requests. Each image only has to be resized once; subsequent requests are served directly from disk.
- Caching doesn’t get in your way – if you modify the source file, the resized versions are also updated.
- You can resize the same image to several different sizes, and the different versions are cached separately.
- Managed disk cache. If the number of cached files exceeds the configured threshold, a cleanup pass is made on the directory, and a block of the least recently used files are removed.
- Client-side caching directives are sent, minimizing repetitive requests from the same client.
- Thumbnail generation in under 20 milliseconds for most images.
- Suitable for slideshows and lists of images. Even the initial resizing of 50 images concurrently isn’t noticeably slow.
- Good with large source files (1-5MB)
- Runs on any of the following following: Windows 2000, Server 2000, XP, Server 2003, Vista, or Server 2008.
- Requires .NET 2.0 or higher to be installed on the server and enabled on the website.
- Users of version 1.0 should get the free upgrade to 1.2 if they wish to use IIS7 Integrated Mode.
While I do charge a download fee, the license allows you to redistribute the source as part of another open-source project. I’m trying to achieve several objectives: 1) Remove the need for users to track licenses, 2) Promote use in open-source projects, 3) Still provide financial support so the project can continue to evolve rapidly.
- Complete source code and an example project is included
- Clean, well documented, well designed code.
- Great platform to build your own image processing systems on. You can use the disk caching system or image processing code independently from each other.
- Very extensible, easy to add new features.
CustomFolders.cs can be *easily* modified to do all kinds of work:
- Build rules to automatically resize images based on folder name or other criteria.
- Add a new syntax for abbreviating or simplifying common resizing operations. Like /resize(w,h)/.
- Easily perform URL rewriting for your images with String.Replace calls. (Regexes work too, if you like them).
By purchasing the download, you are permitted to
- Modify and use the component in all of your projects.
- Redistribute the source code as part of another project, provided the component
is less than 5% of the project (in lines of code), and you keep this information attached. - If you received the source code as part of another open source project,
you cannot extract it (by itself) for use in another project without purchasing a download
from http://nathanaeljones.com/. If nathanaeljones.com is no longer running, and a download
cannot be purchased, then you may extract the code.
This is basically a developer license – if you aren’t a developer (i.e., a hosting company wanting a site or server license), please e-mail me (nathanael.jones@gmail.com).
- Q: Is it possible to specify the width and height, and have your resize and crop to fit the aspect ratio, losing as little image area as possible?
- A: Yes, and it is easy. Use ?width=x&height=y&crop=auto.
- Q: Are animated GIFs supported?
- A: Only one frame is resized. You can choose the frame using &frame=x. Animated GIFs are not supported by .NET, and require lots of extra code.
I’ve developed a custom add-on to the resizer that supports them, but it costs extra. Send me an e-mail if you wish to purchase it. - Q: Are multi-page .TIFFs supported?
- A: Yes – you can convert any page of a multi-page .TIFF to .jpg, .png, or .gif. Use ?page=x&format=jpg
- Q: Can I resize the same image to different sizes?
- A: Yes – there is no limit on how many sizes of an image can be cached.
- Q: Is load balancing across multiple servers supported?
- A: Each server needs its own /imagecache directory. If you disable file system synchronization for /imagecache, it should work fine.
- Q: Do the image names change when they are resized? Is SEO affected?
- A: No, image names are retained – SEO isn’t affected.
- Q: If I resize a photo to its original size, will a new photo be returned, or the original?
- A: All photos are re-compressed, even if the original photo is the same size. This allows ICC correction, file size improvement, and metadata removal.
- Q: Can the resizer both crop, then resize at the same time?
- A: Yes, you can specify a crop rectangle with ?crop=(x1,y1,x2,y2) or ?crop=auto, and add &width=x or any of the resizing commands to resizing the resulting crop.
All commands can be combined. - Q: Can I use this on images not located on the server?
- A: No – it only works for local images. Resizing remote images requires a different architecture, and a different syntax.
Speedy performance is more difficult.
If you are interested in funding this feature, e-mail me. If enough people are interested, they can split the cost of development. - Q: Do the image names change when they are resized? Is SEO affected?
- A: No, image names are retained – SEO isn’t affected.
- Q: When I resize a small image to larger dimensions, it stays at the original size.
- A: This is by design – add &scale=both to allow images to be upscaled. You might want to consider up-scaling client-side to save bandwidth… Just set both width and height on the <img> tag.
- Q: Can I use this with images stored in a database?
- A: Sure, but you’ll have to do a little work. The hard part is done for you, but you’ll need to write the SQL code and call
ImageManager.getBestInstance().BuildImage(). You can pass in a Bitmap object – which can be created from a SQL blob field. The Bitmap that is returned
can be written to disk easily using the ImageOutputSettings class. - Q: Can I use this to resize images as users upload them?
- A: Sure! I suggest keeping the original images around, and using the resizer normally (in case you later want larger images).
However, it’s easy to resize and overwrite an image – 1 line of code.ImageManager.getBestInstance().BuildImage(sourceFile, destFile, new yrl(“?maxwidth=80&maxheight=80&format=png”).QueryString);
- Q: Is in neccessary to wildcard map everything to ASP.NET when using IIS6?
- A: No – you can map .jpg, .png, and .gif individually, but I’ve had numerous reports of IIS issues when using this configuration. I suggest you avoid it.
- Q: I’m seeing a username and password dialog when resizing some images. What is causing this?
- A: You are probably using IIS6, and have inserted individual mappings for .jpg, .gif, and .png instead of using the wildcard mapping as suggested.
The best solution is to add the wildcard mapping. - Q: I asked my hosting company to add the wildcard mapping, but images don’t resize when I add ?width=x; they appear in their original size. I’ve verified that the HttpModule entry is in Web.Config
- A: The tech support person didn’t add the wildcard mapping correctly. Sorry. You can prove it to them by enabling tracing and verifying that the
image requests never reach asp.net.
Add
to your web.config temporarily (never leave it in long on a production site – slows things down).
Visit mysite.com/anyimage.jpg
Visit mysite.com/trace.axd. If the JPG URL isn’t in here, it is impossible that the wildcard mapping is installed correctly. - Q: I’m getting OutOfMemory exceptions when I try to resize certain large images for the first time (subsequent requests are fine). They’re only 15MB in jpeg form, and I have 100MB of free RAM.
- A:
A 15MB JPG uncompresses to about 80MB in bitmap form (depending upon the compression level). If you are resizing to a 2MB jpeg (15MB BMP), memory requirements for the
operation are roughly 110MB (15 + 80 + 15). If you plan on using the resizer for very high-resolution photos (above 8MP), I suggest making sure you have ample amounts of RAM. - Q: I’ve upgraded from the trial version, but I’m still seeing watermarks on my images.
- A: You need to delete the contents of the /imagecache folder, which still contains some cached images generated by the trial version.
- Q: My website is hosted on a UNC share, and it’s not working. I have 2.0a or earlier.
- A: Upgrade. It works in 2.0b.
- Q: I’m getting a .NET security error when resizing GIF images, and when using ?format=png&colors=255. All other image types work fine.
- A: Your hosting provider has messed with the machine.config on the server, and
has prohibited the Marshal class from being used. Upgrade to 2.1+ and set DisableCustomQuantization=true in web.config. GIF quality will be noticeably lower,
but errors should go away. Alternatively, find yourself a better hosting provider. - Q: Image resizing is slow. The number of files in /imagecache/ is constantly hovering around the MaxCachedImages value.
- A: If MaxCachedImages is too low, images will be constantly deleted, then resized again as the get requested next.
- Q: When I resize a dark image, I noticed that there is a 1 pixel border around the image that is slightly brighter than the rest – like a dark gray. What causes this?
- A: This is a bug in Microsoft’s GDI code. I’ve tried over 8 different workarounds, and I don’t think any exist.
I may switch to a different image processing library for this reason, but I’ve had very, very few complaints about the issue. - Q: I’ve written my own code that uses your classes. I’m getting “A generic error occurred in GDI+” with PNGs.
- A: PNGs can only be written to seekable streams (such as files). Response.OutputStream is not seekable.
Use the ImageOutputSettings.SaveImageToNonSeekableStream() method to fix this. Make sure you are using 2.0rc2 or later. - Q: My problem isn’t listed here. What do I do?
- A: First, make sure you are using wildcard mapping instead of individual mappings. And that you are using the latest version.
This is the #1 problem (other than forgetting mappings entirely).
Next, go through the instructions again and double-check your settings.
If that doesn’t help, leave a comment on the main page with
your problem, complete error message (you may have to enable debug=true),
version of IIS, and the URLs you are using.
Looking for the 60+ comments that used to be here? They’re on the old (v1.2) product page.